Reputation: 21
I want to run two functions in parallel which print two lists in parallel. But what I get is one list, being printed after the other list has completed.
I have tried the following code.
import threading
import time
def fun1():
testz=['z','y','x','w','v','u','t']
for j in testz:
print (j)
time.sleep(1)
def fun2():
test=['a','b','c','d','e','f','g']
for i in test:
print (i)
time.sleep(1)
thread1 = threading.Thread(target=fun1())
thread2 = threading.Thread(target=fun2())
thread1.start()
time.sleep(0.5)
thread2.start()
thread1.join()
thread2.join()
The result that I expect for this is :
z
a
y
b
x
c
w
d
v
e
u
f
t
g
but what I get is :
z
y
x
w
v
u
t
a
b
c
d
e
f
g
which seems like the two threads are being run one after the other.
Upvotes: 1
Views: 4525
Reputation: 15
Problem with your code was:
thread1 = threading.Thread(target=fun1())
thread2 = threading.Thread(target=fun2())
Here, it was called function as whole in main thread itself. That is, both function are being called with same threadID
<_MainThread(MainThread, started 4339086784)>
z
y
x
w
v
u
t
<_MainThread(MainThread, started 4339086784)>
a
b
c
d
e
f
g
Proper, syntax for creating threading object should be :
thread1 = threading.Thread(target=fun1)
thread2 = threading.Thread(target=fun2)
After changing : Output
z
a
y
b
x
c
w
d
v
e
u
f
t
g
Upvotes: 1
Reputation: 1180
The problem is that you run the functions in the main thread, not in a subthread. You call the functions first, before giving the returned valued as thread target. Your code should be:
thread1 = threading.Thread(target=fun1)
thread2 = threading.Thread(target=fun2)
Then you will get the expected result.
Upvotes: 4
Reputation: 341
Your first thread finishes before you start the second since you have a sleep there and also you are executing the functions. You should pass the callable to the thread (passing the function without the ()). You cannot guarantee that your code is going to behave as you expect and give you the same result in each execution.
If you don't need threading you can use a simple zip:
for a, b in zip(list1, list2):
print(a)
print(b)
if you really need multithreading and each element of th elist executed in turns you can look at Condition() to lock the threads and use acquire() and release() methods.
Upvotes: -1
Reputation: 413
At creation of your threads you pass the result of fun1
/ fun2
as target instead of the function itself. This is the reason why the functions are executed instantly instead, and not just after you start the thread.
Try to replace your thread-creation with
thread1 = threading.Thread(target=fun1)
thread2 = threading.Thread(target=fun2)
Upvotes: 1
Reputation: 101
If you run the your code in interactive mode, you will get the following output
>>> import threading
>>> import time
>>>
>>> def fun1():
... testz=['z','y','x','w','v','u','t']
... for j in testz:
... print (j)
... time.sleep(1)
...
>>> def fun2():
... test=['a','b','c','d','e','f','g']
... for i in test:
... print (i)
... time.sleep(1)
...
>>>
>>> thread1 = threading.Thread(target=fun1())
z
y
x
w
v
u
t
>>> thread2 = threading.Thread(target=fun2())
a
b
c
d
e
f
g
>>>
>>> thread1.start()
>>> time.sleep(0.5)
>>> thread2.start()
>>>
>>> thread1.join()
>>> thread2.join()
You can see that as soon as you create a thread for fun1()
with thread1 = threading.Thread(target=fun1())
, fun1()
is executed.
Similarly as soon as the thread is created for fun2()
it is executed.
Thus both the functions are not actually running parallelly and you are getting that output.
Upvotes: 1
Reputation: 301
Threading does not make code run in parallel, it provides the illusion of running code in parallel. This falls under the bigger umbrella of concurrency.
You are creating two threads. A thread is going to do some job, and the OS can shut it down at any point to give resources to another thread. Then stop the other thread, and continue on with the initial one. It will do this seemingly randomly.
Printing elements of these lists occurs so fast, that the thread was never stopped by the OS. Also, be aware that printing with threads can lead to race conditions. Essentially, odd behaviour that can be difficult to debug. Do some fuzzing, basically add a sleep
with random numbers for each iteration, sleep(random.random())
, and you will see these race conditions come alive.
If you want the literal print output you stated in your question, you can do as follows:
from itertools import chain
for i in chain(*zip(list1, list2)):
print(i)
Upvotes: 0