Reputation:
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)>
Upvotes: 12
Views: 626
Reputation: 5613
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
Upvotes: 4
Reputation: 569
Probably you do not understand how threads are working. Read this carefully.
I highly suggest you to use ThreadPoolExecutor
from the futures
library.
Upvotes: 2
Reputation: 402
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.
Upvotes: 2
Reputation: 742
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.
Upvotes: 0