472,143 Members | 1,466 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,143 software developers and data experts.

a bug in python windows service?

I feel really puzzled about fellowing code, please help me finger out
what problem here.

import threading

class workingthread(threading.Thread):
def __init__(self):
self.quitEvent = threading.Event()
self.waitTime = 10
threading.Thread.__init__(self)

def run(self):
while not self.quitEvent.isSet():
self.quitEvent.wait(self.waitTime)

def join(self, timeout = None):
self.quitEvent.set()
threading.Thread.join(self, timeout)

import win32serviceutil
import win32event

class testTime(win32serviceutil.ServiceFramework):
_svc_name_ = "testTime"
_svc_display_name_ = "testTime"
_svc_deps_ = ["EventLog"]

def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.thread = workingthread()

def SvcStop(self):
win32event.SetEvent(self.hWaitStop)

def SvcDoRun(self):
self.thread.run()
win32event.WaitForSingleObject(self.hWaitStop,
win32event.INFINITE)
self.thread.join()

if __name__ == '__main__':
win32serviceutil.HandleCommandLine(testTime)

each time I got the fellowing result, anyone can point out what's
wrong in it?

E:\code\monitor2>testTime.py debug
Debugging service testTime- press Ctrl+C to stop.
Stopping debug service.
Error 0xC0000003 - The instance's SvcRun() method failed

File "C:\Python24\Lib\site-packages\win32\lib\win32serviceutil.py",
line 785,
in SvcRun
self.SvcDoRun()
File "E:\code\monitor2\testTime.py", line 35, in SvcDoRun
self.thread.run()
File "E:\code\monitor2\testTime.py", line 12, in run
self.quitEvent.wait(self.waitTime)
File "C:\Python24\lib\threading.py", line 348, in wait
self.__cond.wait(timeout)
File "C:\Python24\lib\threading.py", line 222, in wait
_sleep(delay)

exceptions.IOError: (4, 'Interrupted function call')

May 27 '07 #1
5 3675
En Sat, 26 May 2007 23:00:45 -0300, momobear <wg****@gmail.comescribió:
I feel really puzzled about fellowing code, please help me finger out
what problem here.

import threading

class workingthread(threading.Thread):
def __init__(self):
self.quitEvent = threading.Event()
self.waitTime = 10
threading.Thread.__init__(self)

def run(self):
while not self.quitEvent.isSet():
self.quitEvent.wait(self.waitTime)

def join(self, timeout = None):
self.quitEvent.set()
threading.Thread.join(self, timeout)

import win32serviceutil
import win32event

class testTime(win32serviceutil.ServiceFramework):
_svc_name_ = "testTime"
_svc_display_name_ = "testTime"
_svc_deps_ = ["EventLog"]

def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.thread = workingthread()

def SvcStop(self):
win32event.SetEvent(self.hWaitStop)

def SvcDoRun(self):
self.thread.run()
win32event.WaitForSingleObject(self.hWaitStop,
win32event.INFINITE)
self.thread.join()
No, this is not a bug. You must not call Thread.run(), use Thread.start()
instead - else your code won't run in a different thread of execution. See
http://docs.python.org/lib/thread-objects.html on how to use Thread
objects - and note that you should *only* override __init__ and run, if
any.
Instead of extending join(), write a specific method to signal the
quitEvent or just let the caller signal it. And I don't see in this
example why do you need two different events (one on the thread, another
on the service controller), a single event would suffice.

--
Gabriel Genellina

May 27 '07 #2
No, this is not a bug. You must not call Thread.run(), use Thread.start()
instead - else your code won't run in a different thread of execution. See http://docs.python.org/lib/thread-objects.htmlon how to use Thread
objects - and note that you should *only* override __init__ and run, if
any.
Instead of extending join(), write a specific method to signal the
quitEvent or just let the caller signal it. And I don't see in this
example why do you need two different events (one on the thread, another
on the service controller), a single event would suffice.

--
Gabriel Genellina
Thanks for help, It works now:D
May 27 '07 #3
Instead of extending join(), write a specific method to signal the
quitEvent or just let the caller signal it. And I don't see in this
example why do you need two different events (one on the thread, another
on the service controller), a single event would suffice.
I don't think a single event is enought, since I think the event
python created and windows event are not same kind of event.
May 27 '07 #4
En Sun, 27 May 2007 09:07:36 -0300, momobear <wg****@gmail.comescribió:
>Instead of extending join(), write a specific method to signal the
quitEvent or just let the caller signal it. And I don't see in this
example why do you need two different events (one on the thread, another
on the service controller), a single event would suffice.

I don't think a single event is enought, since I think the event
python created and windows event are not same kind of event.
They are not the same object, of course (altough the threading.Event
object relies eventually on a mutex implemented using CreateEvent). But in
this case both can be successfully used; of course, having the Python
object a more "pythonic" interfase (not a surprise!), it's easier to use.
The same example modified using only a threading.Event object (and a few
messages to verify how it runs):

import threading
from win32api import OutputDebugString as ODS

class workingthread(threading.Thread):
def __init__(self, quitEvent):
self.quitEvent = quitEvent
self.waitTime = 1
threading.Thread.__init__(self)

def run(self):
while not self.quitEvent.isSet():
ODS("Running...\n")
self.quitEvent.wait(self.waitTime)
ODS("Exit run.\n")
import win32serviceutil
import win32event

class testTime(win32serviceutil.ServiceFramework):
_svc_name_ = "testTime"
_svc_display_name_ = "testTime"
_svc_deps_ = ["EventLog"]

def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = threading.Event()
self.thread = workingthread(self.hWaitStop)

def SvcStop(self):
self.hWaitStop.set()

def SvcDoRun(self):
self.thread.start()
self.hWaitStop.wait()
self.thread.join()

if __name__ == '__main__':
win32serviceutil.HandleCommandLine(testTime)

--
Gabriel Genellina

May 27 '07 #5
On May 27, 11:25 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
En Sun, 27 May 2007 09:07:36 -0300, momobear <wgw...@gmail.comescribió:
Instead of extending join(), write a specific method to signal the
quitEvent or just let the caller signal it. And I don't see in this
example why do you need two different events (one on the thread, another
on the service controller), a single event would suffice.
I don't think a single event is enought, since I think the event
python created and windows event are not same kind of event.

They are not the same object, of course (altough the threading.Event
object relies eventually on a mutex implemented using CreateEvent). But in
this case both can be successfully used; of course, having the Python
object a more "pythonic" interfase (not a surprise!), it's easier to use.
The same example modified using only a threading.Event object (and a few
messages to verify how it runs):

import threading
from win32api import OutputDebugString as ODS

class workingthread(threading.Thread):
def __init__(self, quitEvent):
self.quitEvent = quitEvent
self.waitTime = 1
threading.Thread.__init__(self)

def run(self):
while not self.quitEvent.isSet():
ODS("Running...\n")
self.quitEvent.wait(self.waitTime)
ODS("Exit run.\n")

import win32serviceutil
import win32event

class testTime(win32serviceutil.ServiceFramework):
_svc_name_ = "testTime"
_svc_display_name_ = "testTime"
_svc_deps_ = ["EventLog"]

def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = threading.Event()
self.thread = workingthread(self.hWaitStop)

def SvcStop(self):
self.hWaitStop.set()

def SvcDoRun(self):
self.thread.start()
self.hWaitStop.wait()
self.thread.join()

if __name__ == '__main__':
win32serviceutil.HandleCommandLine(testTime)

--
Gabriel Genellina
Great! thanks, now I understand the real work of the python windows
service.

May 28 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Gandalf | last post: by
reply views Thread by David Mitchell | last post: by
3 posts views Thread by David Fraser | last post: by
8 posts views Thread by Saravanan | last post: by
reply views Thread by Saravanan | last post: by
8 posts views Thread by Jan Gregor | last post: by
reply views Thread by Stefan Krah | last post: by
1 post views Thread by Aspersieman | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.