start.py code is as below.
import threading class myThread(threading.Thread): def __init__(self, threadID, name): threading.Thread.__init__(self) self.threadID = threadID self.name = name def run(self): currentThreadname = threading.currentThread() print "running in ", currentThreadname thread = myThread(1,"mythrd") thread.start()
Start it with python for two times.
python start.py running in <myThread(mythrd, started 140461133485824)> python start.py running in <myThread(mythrd, started 140122860668672)>
run.py code is as below.
import threading class myThread(threading.Thread): def __init__(self, threadID, name): threading.Thread.__init__(self) self.threadID = threadID self.name = name def run(self): currentThreadname = threading.currentThread() print "running in ", currentThreadname thread = myThread(1,"mythrd") thread.run()
run.py is only one line different from start.py.
Now start run.py for two times.
python run.py running in <_MainThread(MainThread, started 139854546364160)> python run.py running in <_MainThread(MainThread, started 139854546364160)>
startandrun.py code is as below.
class myThread(threading.Thread): def __init__(self, threadID, name): threading.Thread.__init__(self) self.threadID = threadID self.name = name def run(self): currentThreadname = threading.currentThread() print "running in ", currentThreadname thread = myThread(1,"mythrd") thread.start() thread.run()
Now start startandrun.py for two times also.
python startandrun.py running in <myThread(mythrd, started 140317119899392)> running in <_MainThread(MainThread, started 140317144454912)> python startandrun.py running in running in <_MainThread(MainThread, started 139980210505472)> <myThread(mythrd, started 139980185949952)>
As JohanL say:
When running two separate threads, all bets are off as to which will execute first.
You are basically leaving the scheduling to the operating system. The first time to execute startandrun.py, thread.start()
was executed before thread.run()
,it result in the output:
running in <myThread(mythrd, started 140317119899392)> running in <_MainThread(MainThread, started 140317144454912)>
The second time to execute startandrun.py, thread.start()
was executed after thread.run()
,why not result in the output:
running in <_MainThread(MainThread, started 140317144454912)> running in <myThread(mythrd, started 140317119899392)>
instead of
running in running in <_MainThread(MainThread, started 139980210505472)> <myThread(mythrd, started 139980185949952)>
???
4 Answers
Answers 1
This is happening because of the way you are printing the values:
print "running in ", currentThreadname
Adding a comma is similar to:
print 'running in ' # without new line at the end print currentThreadname
And since the two functions are running at the same time here is how the order is executed:
print 'running in ' # without new line FUNCTION #1 print 'running in ' # without new line FUNCTION #2 print currentThreadName # with new line at the end FUNCTION #1 print currentThreadName # with new line at the end FUNCTION #2
Try using one print statement without commas to understand how it should be:
def run(self): currentThreadname = threading.currentThread() print "running in {}".format(currentThreadname)
This will behave normally but since the two functions are printing at the same time, you might get the following output:
running in <myThread(mythrd, started 10716)>running in <_MainThread(MainThread, started 12132)>
So to prove that this will work you can use a delay in between the two calls using time.sleep()
:
import threading import time class myThread(threading.Thread): def __init__(self, threadID, name): threading.Thread.__init__(self) self.threadID = threadID self.name = name def run(self): currentThreadname = threading.currentThread() print "running in {}".format(currentThreadname) thread = myThread(1,"mythrd") thread.start() time.sleep(0.1) thread.run()
Now you can see that you get your desired output because each function is printing one time with a 0.1 sec delay in between the calls:
running in <myThread(mythrd, started 5600)> running in <_MainThread(MainThread, started 7716)>
EDIT:
Your issue is exactly why you should use multithreading instead of running the same thread twice. When you use multithreading You can use thread.join()
which will wait for the thread to finish off and then continue the code, or you can use threading.lock()
so you can continue your code but lock a function to be used by one thread at a time. Here are some examples:
thread.join():
thread = myThread(1, "mythrd") thread2 = myThread(2, "thrd2") thread.start() thread.join() # code will stop here and wait for thread to finish then continue thread2.run()
threading.lock():
.... def run(self): with lock: # if one thread uses this lock the other threads have to wait currentThreadname = threading.currentThread() print "running in ", currentThreadname thread = myThread(1, "mythrd") thread2 = myThread(2, "thrd2") lock = threading.Lock() thread.start() thread2.run() # code keeps running even if there are threads waiting for the lock
Answers 2
So, all you want is to synchronize your threads. It can be done easily using the join() function in threading library.
You can do something like this
class myThread(threading.Thread): def __init__(self, threadID, name): threading.Thread.__init__(self) self.threadID = threadID self.name = name def run(self): currentThreadname = threading.currentThread() print "running in ", currentThreadname thread = myThread(1,"mythrd") t1 = thread.start() t1.join() t2 = thread.run() t2.join()
You can also use semaphore and Lock for better reasons. See the docs for more detail.
Answers 3
Probably you do not understand how threads are working. Read this carefully.
I highly suggest you to use ThreadPoolExecutor
from the futures
library.
Answers 4
What version python were you using? In python 2, "print" is not thread safe. Please see http://tech.queryhome.com/54593/is-print-thread-safe-in-python-2-6-2-7.
If threads switch during "print", the outputs are mixed, like what you saw.
0 comments:
Post a Comment