By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,068 Members | 1,734 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,068 IT Pros & Developers. It's quick & easy.

Stopping a Thread with Time Slicing

P: n/a
Hi All,

I've been trying to come up with a good way to run a certain process
at a timed interval (say every 5 mins) using the SLEEP command and a
semaphore flag. The basic thread loop was always sitting in the sleep
command and not able to be interrupted. When the time came to set the
semaphore flag to false (stopping the thread), my program would have
to wait up to the entire sleep time to break out of the loop.

I have finally found a very workable solution to break out of the
sleep loop by using a time slicing loop to divide the overall sleep
time into small pieces (slices) giving the loop more opportunities to
be interrupted.
Here is my code :

-------------------------------------------------------------

import time
import datetime
import threading
def log(message):

now = datetime.datetime.now().strftime("%H:%M:%S")
print "%s : %s" % (now, message)

class StoppableThread(threading.Thread):

def __init__(self, sleep_time, time_slice):

self.sleep_time = sleep_time
self.running = True
self.time_slice = time_slice

threading.Thread.__init__(self)
def run(self):

while self.running:

log('Thread Running...')
#process_some_data() ## <<-- Call some def here to perform
some timed task
log('## Do Some Work Here ##\n')

# Sleep Loop :
# Put sleeps in time_slice loop, with sleep = sleep_time /
time_slice
# This gives the sleep loop more opportunities to be interrupted
# when the running flag is set to False

for current_loop in range(0, self.time_slice) :

time.sleep(self.sleep_time / self.time_slice)

if not self.running: # check the flag
break # break out of the sleep loop
log('** Thread Has STOPPED!')
def stop(self): # stop the thread from running
self.running = False
################################################## ###################
# T E S T
################################################## ###################

SMALL_SLEEP = 35
CHECK_SLEEP = 300 # sleep interval in seconds to run a timed
process
TIME_SLICE = 100 # number of slices to divide CHECK_TIME
(higher number = faster kill response)
log('Create Thread')
thread_obj = StoppableThread(CHECK_SLEEP, TIME_SLICE)

log('Thread Start\n')
thread_obj.start()

for current_loop in range(0,10):
time.sleep(SMALL_SLEEP)
log('current loop = %d \n' % current_loop)

log('Thread Stop')
thread_obj.stop()

log('Done!')
--------------------------------------------

Test Results :
>python Simple_Thread.py
15:37:23 : Create Thread
15:37:23 : Thread Start

15:37:23 : Thread Running...
15:37:23 : ## Do Some Work Here ##

15:37:58 : current loop = 0

15:38:33 : current loop = 1

15:39:08 : current loop = 2

15:39:43 : current loop = 3

15:40:18 : current loop = 4

15:40:53 : current loop = 5

15:41:28 : current loop = 6

15:42:03 : current loop = 7

15:42:23 : Thread Running...
15:42:23 : ## Do Some Work Here ##

15:42:38 : current loop = 8

15:43:13 : current loop = 9

15:43:13 : Thread Stop
15:43:13 : Done!
15:43:14 : ** Thread Has STOPPED!
Oct 2 '08 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Steve wrote:
Hi All,

I've been trying to come up with a good way to run a certain process
at a timed interval (say every 5 mins) using the SLEEP command and a
semaphore flag. The basic thread loop was always sitting in the sleep
command and not able to be interrupted. When the time came to set the
semaphore flag to false (stopping the thread), my program would have
to wait up to the entire sleep time to break out of the loop.

I have finally found a very workable solution to break out of the
sleep loop by using a time slicing loop to divide the overall sleep
time into small pieces (slices) giving the loop more opportunities to
be interrupted.
A better approach for this is to use a Python Event or Condition object:
http://docs.python.org/library/threading.html#id5

Example code:
import threading
my_stop_event = threading.Event()

# Sleep Loop :
#for current_loop in range(0, self.time_slice) :
# time.sleep(self.sleep_time / self.time_slice)

event.wait(self.sleep_time)
if not self.running: # check the flag
break # break out of the sleep loop

# From another thread, you can notify the above sleeping thread using:
my_stop_event.set()
Cheers,
Todd
Oct 2 '08 #2

P: n/a
Hi Todd,

Thanks for your suggestions on using the Event condition methods on
this thread.

Here is my updated code :
import time
import datetime
import threading
def log(message):

now = datetime.datetime.now().strftime("%H:%M:%S")
print "%s : %s" % (now, message)

class StoppableThread(threading.Thread):

def __init__(self, sleep_time, function, args=[], kwargs={}):

self.sleep_time = sleep_time

threading.Thread.__init__(self)

self.function = function
self.args = args
self.kwargs = kwargs
self.finished = threading.Event()
def run(self):

while not self.finished.isSet(): # loop while condition
is true
log('** Doing Work')
self.function(*self.args, **self.kwargs) # run the function
self.finished.wait(self.sleep_time) # put thread in wait
state
log('** Thread Has STOPPED!')
def stop(self): # stop the thread from running
log('* Stopping Thread')
self.finished.set()
self.join()


def my_function (a, b, c):
log('my_function running... %s' % a)
################################################## ###################
# T E S T
################################################## ###################

SMALL_SLEEP = 35
CHECK_SLEEP = 300 # sleep interval in seconds to run a timed
process
log('Create Thread')
thread_obj = StoppableThread(CHECK_SLEEP, my_function, (15,0,-1))
log('Thread Start\n')
thread_obj.start()

for current_loop in range(0,10):
time.sleep(SMALL_SLEEP)
log('current loop = %d \n' % current_loop)

log('Call Thread Stop')
thread_obj.stop()

log('Done!')
Test Output :
>python Simple_Thread_Stop_Event.py
12:58:42 : Create Thread
12:58:42 : Thread Start

12:58:42 : ** Doing Work
12:58:42 : my_function running... 15
12:59:17 : current loop = 0
12:59:52 : current loop = 1
13:00:27 : current loop = 2
13:01:02 : current loop = 3
13:01:37 : current loop = 4
13:02:12 : current loop = 5
13:02:47 : current loop = 6
13:03:22 : current loop = 7
13:03:42 : ** Doing Work
13:03:42 : my_function running... 15
13:03:57 : current loop = 8

13:04:32 : current loop = 9

13:04:32 : Call Thread Stop
13:04:32 : * Stopping Thread
13:04:32 : ** Thread Has STOPPED!
13:04:32 : Done!
On Oct 2, 4:40*pm, Todd Whiteman <to...@activestate.comwrote:
Steve wrote:

A better approach for this is to use a Python Event or Condition object:http://docs.python.org/library/threading.html#id5

Example code:

import threading
my_stop_event = threading.Event()

* * * *# Sleep Loop :
* * * *#for current_loop in range(0, self.time_slice) :
* * * *# *time.sleep(self.sleep_time / self.time_slice)

* * * *event.wait(self.sleep_time)
* * * *if not self.running: * *# check the flag
* * * * *break * * * * * * * * # break out of the sleep loop

# From another thread, you can notify the above sleeping thread using:
my_stop_event.set()

Cheers,
Todd
Oct 3 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.