Python running two threads simultaneously [duplicate] - python

This question already has answers here:
Terminate multiple threads when any thread completes a task
(5 answers)
Closed 8 years ago.
Is it possible to run two threads simultaneously? For example...
I have two classes like this...
import threading
class Thread1(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print("Thread1")
class justAClass(object):
def do_soemthing(self):
print("Thread2")
if __name__ == "__main__":
total = 0
thread_limit = 200
while True:
if threading.activeCount() < thread_limit:
Thread1().start()
# I will never run because I want to wait until while True has finished to run!
t = threading.Timer(1.0, justAClass().do_soemthing())
t.start()
If you run this code you will see that Tread2 never gets printed out because the Thread2 has to wait for Thread1 to finished (which it never will because of the While statement.
What I'm after is for both Thread1 and Thread2 to run at the same time independent of each other.

while True:
if threading.activeCount() < thread_limit:
Thread1().start()
# I will never run because I want to wait until while True has finished to run!
t = threading.Timer(1.0, justAClass().do_soemthing())
t.start()
obviously that's the case! And as you're never getting out of the loop, the code below the comment is unreachable.
Though, your first code was:
tor.connect()
tor.new_identity()
t = threading.Timer(10.0, tor.new_identity())
t.start()
total = 0
thread_limit = 200
while True:
if threading.activeCount() < thread_limit:
stress_test(host_ip, host_port).start()
And there you were initiating the Timer before the infinite loop, so your Timer thread was definitely working, as we said in our comments. To make your SSCCE work correctly, here comes the fix:
import threading
import time
class Thread1(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
time.sleep(1)
print("Thread1")
class justAClass(object):
def do_something(self, pause):
while True:
time.sleep(pause)
print("Thread2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
if __name__ == "__main__":
total = 0
thread_limit = 200
t = threading.Timer(1.0, justAClass().do_something, args=(1.0,))
t.start()
while True:
if threading.activeCount() < thread_limit:
Thread1().start()
Though, be aware that your timer thread, with the do_something function as it is, will only run once, unless you rearm it from within the thread, or you build a while loop within.
BTW, I fixed another mistake in your code I did not see at first, you're calling the
timer over the do_something function, be if you pass the do_something function with
parens at the end do_something(), it will be evaluated in your main thread as you're
creating the timer, and then you'll be passing the result of the function to the Timer
function... Whereas if you do not use the parens, you're giving the function object itself
to Timer() which will then be able to call it after the delay.
is there a way to get the timer to run every x seconds while still allowing the other function to run?
of course:
class justAClass(object):
def do_something(self, pause):
while True:
time.sleep(pause)
print("Thread2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")

Related

Stopping eval code dinamically on event fired [duplicate]

What's the proper way to tell a looping thread to stop looping?
I have a fairly simple program that pings a specified host in a separate threading.Thread class. In this class it sleeps 60 seconds, the runs again until the application quits.
I'd like to implement a 'Stop' button in my wx.Frame to ask the looping thread to stop. It doesn't need to end the thread right away, it can just stop looping once it wakes up.
Here is my threading class (note: I haven't implemented looping yet, but it would likely fall under the run method in PingAssets)
class PingAssets(threading.Thread):
def __init__(self, threadNum, asset, window):
threading.Thread.__init__(self)
self.threadNum = threadNum
self.window = window
self.asset = asset
def run(self):
config = controller.getConfig()
fmt = config['timefmt']
start_time = datetime.now().strftime(fmt)
try:
if onlinecheck.check_status(self.asset):
status = "online"
else:
status = "offline"
except socket.gaierror:
status = "an invalid asset tag."
msg =("{}: {} is {}. \n".format(start_time, self.asset, status))
wx.CallAfter(self.window.Logger, msg)
And in my wxPyhton Frame I have this function called from a Start button:
def CheckAsset(self, asset):
self.count += 1
thread = PingAssets(self.count, asset, self)
self.threads.append(thread)
thread.start()
Threaded stoppable function
Instead of subclassing threading.Thread, one can modify the function to allow
stopping by a flag.
We need an object, accessible to running function, to which we set the flag to stop running.
We can use threading.currentThread() object.
import threading
import time
def doit(arg):
t = threading.currentThread()
while getattr(t, "do_run", True):
print ("working on %s" % arg)
time.sleep(1)
print("Stopping as you wish.")
def main():
t = threading.Thread(target=doit, args=("task",))
t.start()
time.sleep(5)
t.do_run = False
if __name__ == "__main__":
main()
The trick is, that the running thread can have attached additional properties. The solution builds
on assumptions:
the thread has a property "do_run" with default value True
driving parent process can assign to started thread the property "do_run" to False.
Running the code, we get following output:
$ python stopthread.py
working on task
working on task
working on task
working on task
working on task
Stopping as you wish.
Pill to kill - using Event
Other alternative is to use threading.Event as function argument. It is by
default False, but external process can "set it" (to True) and function can
learn about it using wait(timeout) function.
We can wait with zero timeout, but we can also use it as the sleeping timer (used below).
def doit(stop_event, arg):
while not stop_event.wait(1):
print ("working on %s" % arg)
print("Stopping as you wish.")
def main():
pill2kill = threading.Event()
t = threading.Thread(target=doit, args=(pill2kill, "task"))
t.start()
time.sleep(5)
pill2kill.set()
t.join()
Edit: I tried this in Python 3.6. stop_event.wait() blocks the event (and so the while loop) until release. It does not return a boolean value. Using stop_event.is_set() works instead.
Stopping multiple threads with one pill
Advantage of pill to kill is better seen, if we have to stop multiple threads
at once, as one pill will work for all.
The doit will not change at all, only the main handles the threads a bit differently.
def main():
pill2kill = threading.Event()
tasks = ["task ONE", "task TWO", "task THREE"]
def thread_gen(pill2kill, tasks):
for task in tasks:
t = threading.Thread(target=doit, args=(pill2kill, task))
yield t
threads = list(thread_gen(pill2kill, tasks))
for thread in threads:
thread.start()
time.sleep(5)
pill2kill.set()
for thread in threads:
thread.join()
This has been asked before on Stack. See the following links:
Is there any way to kill a Thread in Python?
Stopping a thread after a certain amount of time
Basically you just need to set up the thread with a stop function that sets a sentinel value that the thread will check. In your case, you'll have the something in your loop check the sentinel value to see if it's changed and if it has, the loop can break and the thread can die.
I read the other questions on Stack but I was still a little confused on communicating across classes. Here is how I approached it:
I use a list to hold all my threads in the __init__ method of my wxFrame class: self.threads = []
As recommended in How to stop a looping thread in Python? I use a signal in my thread class which is set to True when initializing the threading class.
class PingAssets(threading.Thread):
def __init__(self, threadNum, asset, window):
threading.Thread.__init__(self)
self.threadNum = threadNum
self.window = window
self.asset = asset
self.signal = True
def run(self):
while self.signal:
do_stuff()
sleep()
and I can stop these threads by iterating over my threads:
def OnStop(self, e):
for t in self.threads:
t.signal = False
I had a different approach. I've sub-classed a Thread class and in the constructor I've created an Event object. Then I've written custom join() method, which first sets this event and then calls a parent's version of itself.
Here is my class, I'm using for serial port communication in wxPython app:
import wx, threading, serial, Events, Queue
class PumpThread(threading.Thread):
def __init__ (self, port, queue, parent):
super(PumpThread, self).__init__()
self.port = port
self.queue = queue
self.parent = parent
self.serial = serial.Serial()
self.serial.port = self.port
self.serial.timeout = 0.5
self.serial.baudrate = 9600
self.serial.parity = 'N'
self.stopRequest = threading.Event()
def run (self):
try:
self.serial.open()
except Exception, ex:
print ("[ERROR]\tUnable to open port {}".format(self.port))
print ("[ERROR]\t{}\n\n{}".format(ex.message, ex.traceback))
self.stopRequest.set()
else:
print ("[INFO]\tListening port {}".format(self.port))
self.serial.write("FLOW?\r")
while not self.stopRequest.isSet():
msg = ''
if not self.queue.empty():
try:
command = self.queue.get()
self.serial.write(command)
except Queue.Empty:
continue
while self.serial.inWaiting():
char = self.serial.read(1)
if '\r' in char and len(msg) > 1:
char = ''
#~ print('[DATA]\t{}'.format(msg))
event = Events.PumpDataEvent(Events.SERIALRX, wx.ID_ANY, msg)
wx.PostEvent(self.parent, event)
msg = ''
break
msg += char
self.serial.close()
def join (self, timeout=None):
self.stopRequest.set()
super(PumpThread, self).join(timeout)
def SetPort (self, serial):
self.serial = serial
def Write (self, msg):
if self.serial.is_open:
self.queue.put(msg)
else:
print("[ERROR]\tPort {} is not open!".format(self.port))
def Stop(self):
if self.isAlive():
self.join()
The Queue is used for sending messages to the port and main loop takes responses back. I've used no serial.readline() method, because of different end-line char, and I have found the usage of io classes to be too much fuss.
Depends on what you run in that thread.
If that's your code, then you can implement a stop condition (see other answers).
However, if what you want is to run someone else's code, then you should fork and start a process. Like this:
import multiprocessing
proc = multiprocessing.Process(target=your_proc_function, args=())
proc.start()
now, whenever you want to stop that process, send it a SIGTERM like this:
proc.terminate()
proc.join()
And it's not slow: fractions of a second.
Enjoy :)
My solution is:
import threading, time
def a():
t = threading.currentThread()
while getattr(t, "do_run", True):
print('Do something')
time.sleep(1)
def getThreadByName(name):
threads = threading.enumerate() #Threads list
for thread in threads:
if thread.name == name:
return thread
threading.Thread(target=a, name='228').start() #Init thread
t = getThreadByName('228') #Get thread by name
time.sleep(5)
t.do_run = False #Signal to stop thread
t.join()
I find it useful to have a class, derived from threading.Thread, to encapsulate my thread functionality. You simply provide your own main loop in an overridden version of run() in this class. Calling start() arranges for the object’s run() method to be invoked in a separate thread.
Inside the main loop, periodically check whether a threading.Event has been set. Such an event is thread-safe.
Inside this class, you have your own join() method that sets the stop event object before calling the join() method of the base class. It can optionally take a time value to pass to the base class's join() method to ensure your thread is terminated in a short amount of time.
import threading
import time
class MyThread(threading.Thread):
def __init__(self, sleep_time=0.1):
self._stop_event = threading.Event()
self._sleep_time = sleep_time
"""call base class constructor"""
super().__init__()
def run(self):
"""main control loop"""
while not self._stop_event.isSet():
#do work
print("hi")
self._stop_event.wait(self._sleep_time)
def join(self, timeout=None):
"""set stop event and join within a given time period"""
self._stop_event.set()
super().join(timeout)
if __name__ == "__main__":
t = MyThread()
t.start()
time.sleep(5)
t.join(1) #wait 1s max
Having a small sleep inside the main loop before checking the threading.Event is less CPU intensive than looping continuously. You can have a default sleep time (e.g. 0.1s), but you can also pass the value in the constructor.
Sometimes you don't have control over the running target. In those cases you can use signal.pthread_kill to send a stop signal.
from signal import pthread_kill, SIGTSTP
from threading import Thread
from itertools import count
from time import sleep
def target():
for num in count():
print(num)
sleep(1)
thread = Thread(target=target)
thread.start()
sleep(5)
pthread_kill(thread.ident, SIGTSTP)
result
0
1
2
3
4
[14]+ Stopped

How to run infinite loops within threading in python

I've looked everywhere and it seems like the threads I write should work. I've checked many other threads about it and tutorials. I can't seem to run infinite loops in threads. Despite what I do, only the first thread works/prints.
Here is the code for just methods.
import threading
def thread1():
while True:
print("abc")
def thread2():
while True:
print ("123")
if __name__ == "__main__":
t1 = threading.Thread(target=thread1())
t2 = threading.Thread(target=thread2())
t1.start
t2.start
t1.join
t2.join
Removing the prentheses at the end of calling the functions with target=causes nothing to print so I keep that in there.
Here is the class/object version.
from threading import Thread
class Thread1(Thread):
def __init__(self):
Thread.__init__(self)
self.daemon = True
self.start
def run():
while True:
print ("abc")
class Thread2(Thread):
def __init__(self):
Thread.__init__(self)
self.daemon = True
self.start
def run():
while True:
print ("123")
Thread1.run()
Thread2.run()
both never get to printing 123 and I can't figure out why. It looks like infinite loops shouldn't be an issue because they are being run in parallel. I tried time.sleep (bc maybe the GIL stopped it idk) so thread2 could run while thread1 was idle. Didn't work.
For the first example:
if __name__ == "__main__":
t1 = threading.Thread(target=thread1)
t2 = threading.Thread(target=thread2)
t1.start()
t2.start()
t1.join()
t2.join()
Pass the function, not the result of calling the function, to threading.Thread as its target.
For the section example. Don't call run. Call start. After creating an instance.
from threading import Thread
class Thread1(Thread):
def __init__(self):
Thread.__init__(self)
self.daemon = True
def run():
while True:
print ("abc")
class Thread2(Thread):
def __init__(self):
Thread.__init__(self)
self.daemon = True
def run():
while True:
print ("123")
Thread1().start()
Thread2().start()
Your parentheses are in the wrong places in the first version.
As currently written, you are passing the result of calling thread1 when creating t1; since that call never returns, you never actually create a thread. So you need to remove those parentheses.
But you don't include the parentheses where you are trying to call the start and join methods, so the threads never actually got started even when you didn't use the extra parentheses when creating the threads.

how can stop only thread but program should keep running in python

import time
import threading
class Check(threading.Thread):
def __init__(self):
self.stopped = False
threading.Thread.__init__(self)
def run(self):
i = 0
while not self.stopped:
time.sleep(1)
i = i + 1
print(i)
if(i==5):
self.stopped = True
inst = Check()
inst.start()
You have to set up your own mechanism for stopping a thread--Python doesn't have a built-in way to do it. This is actually a common problem among many languages, not just Python.
import time
import threading
class Check(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
# An event can be useful here, though a simple boolean works too since
# assignment is atomic in Python.
self.stop_event = threading.Event()
def run(self):
i = 0
while not self.stop_event.is_set():
time.sleep(1)
i = i + 1
print(i)
if(i==5):
self.stopped = True
def stop(self):
# Tell the thread to stop...
self.stop_event.set()
# Wait for the thread to stop
self.join()
inst = Check()
inst.start()
# Do stuff...
time.sleep(1)
inst.stop()
# Thread has stopped, but the main thread is still running...
print("I'm still here!")
Here I use an event to signal whether or not the thread should stop. We add a stop method to signal the event and then wait for the thread to finish processing before continuing. This is very simplistic, but hopefully it gives you the idea of the kind of strategy you can take. It gets much more complicated if you want to handle error conditions like being informed if an error occurred in the run() method or if the body of the run() method is taking too long, etc.

killing a thread in python before its done [duplicate]

This question already has answers here:
Is there any way to kill a Thread?
(31 answers)
Closed 8 years ago.
I did a little search and found out there is no way to kill a thread in python, but how would one solve a problem like me ?
I have a function that sets X to True for one hour and after that it sets it back to False.
sometimes the program finishes less than the needed hour, but the thread is still running and make garbage in memory.
def enableX():
self.x=True
sleep(3600)
self.x=False
def function1():
self.enableXThread=Thread(target=self.enableX)
self.enableXThread.start()
any idea ? how I can kill enbableXThread when the program terminates no matter if the thread is done or not ?
how I can kill enbableXThread when the program terminates
If the thread does not have any cleanup to do, make it a daemon thread by setting enableXThread.daemon to True. This must be done before starting the thread:
self.enableXThread = Thread(target=self.enableX)
self.enableXThread.daemon = True
self.enableXThread.start()
Otherwise, use an exit flag (a global variable that the threads check to see whether they should exit) or an Event handler.
You might also considering using a signal for this, as this may be simpler than threading; you can simply set an alarm for an hour and have the handler reset the variable. If your process ends before the alarm goes off, nothing happens. Note that this isn't available on Windows.
import signal
X = False
def handle_alarm(signum, frame):
global X
X = False
signal.signal(signal.SIGALRM, handle_alarm)
def set_X_true_then_false_later(secs=3600):
global X
X = True
signal.alarm(secs)
It looks like your problem has already been solved using kindall's suggestions, but if you ever are interested in being able to terminate a thread from another one, the following might be of interest to you.
If you do not mind your code running about ten times slower, you can use the Thread2 class implemented below. An example follows that shows how calling the new stop method should kill the thread on the next bytecode instruction.
import threading
import sys
class StopThread(StopIteration): pass
threading.SystemExit = SystemExit, StopThread
class Thread2(threading.Thread):
def stop(self):
self.__stop = True
def _bootstrap(self):
if threading._trace_hook is not None:
raise ValueError('Cannot run thread with tracing!')
self.__stop = False
sys.settrace(self.__trace)
super()._bootstrap()
def __trace(self, frame, event, arg):
if self.__stop:
raise StopThread()
return self.__trace
class Thread3(threading.Thread):
def _bootstrap(self, stop_thread=False):
def stop():
nonlocal stop_thread
stop_thread = True
self.stop = stop
def tracer(*_):
if stop_thread:
raise StopThread()
return tracer
sys.settrace(tracer)
super()._bootstrap()
################################################################################
import time
def main():
test = Thread2(target=printer)
test.start()
time.sleep(1)
test.stop()
test.join()
def printer():
while True:
print(time.time() % 1)
time.sleep(0.1)
if __name__ == '__main__':
main()
The Thread3 class appears to run code approximately 33% faster than the Thread2 class.

Non-blocking class in python (detached Thread)

I'm trying to create a kind of non-blocking class in python, but I'm not sure how.
I'd like a class to be a thread itself, detached from the main thread so other threads can interact with it.
In a little example:
#!/usr/bin/python2.4
import threading
import time
class Sample(threading.Thread):
def __init__(self):
super(Sample, self).__init__()
self.status = 1
self.stop = False
def run(self):
while not(self.stop):
pass
def getStatus(self):
return self.status
def setStatus(self, status):
self.status = status
def test(self):
while self.status != 0:
time.sleep(2)
#main
sample = Sample()
sample.start()
sample.test()
sample.setStatus(0)
sample.stop()
What I'd like is having the "sample" instance running as a separate thread (detached from the main one) so, in the example, when the main thread reaches sample.test(), sample (and only "sample") would go to sleep for 2 seconds. In the meanwhile, the main thread would continue its execution and set sample's status to 0. When after the 2 seconds "sample" wakes up it would see the status=0 and exit the while loop.
The problem is that if I do this, the line sample.setStatus(0) is never reached (creating an infinite loop). I have named the threads, and it turns out that by doing this, test() is run by the main thread.
I guess I don't get the threading in python that well...
Thank you in advance
The object's run() method is what executes in a separate thread. When you call sample.test(), that executes in the main thread, so you get your infinite loop.
Perhaps something like this?
import threading
import time
class Sample(threading.Thread):
def __init__(self):
super(Sample, self).__init__()
self.stop = False
def run(self):
while not(self.stop):
print('hi')
time.sleep(.1)
def test(self):
print('testing...')
time.sleep(2)
#main
sample = Sample()
sample.start() # Initiates second thread which calls sample.run()
sample.test() # Main thread calls sample.test
sample.stop=True # Main thread sets sample.stop
sample.join() # Main thread waits for second thread to finish

Categories