codes like
import threading
def job1():
global A
for i in range(10):
A += 1
print('job1', A)
def job2():
global A
for i in range(10):
A += 10
print('job2', A)
if __name__ == '__main__':
A = 0
t1 = threading.Thread(target=job1)
t2 = threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
print('all done')
and I run it on python 3.7.3
the result I want to get is like
job1job2 111
job1job2 1222
job1job2 2333
job1job2 3444
job1job2 4555
job1job2 5666
...
all done
but what did I get is
job1 1
job1 2
job1 3
job1 4
job1 5
job1 6
job1 7
job1 8
job1 9
job1 10
job2 20
job2 30
job2 40
job2 50
job2 60
job2 70
job2 80
job2 90
job2 100
job2 110
all done
But I just did not use the lock!
I think this is the result of the code below:
import threading
def job1():
global A, lock
lock.acquire()
for i in range(10):
A += 1
print('job1', A)
lock.release()
def job2():
global A, lock
lock.acquire()
for i in range(10):
A += 10
print('job2', A)
lock.release()
if __name__ == '__main__':
A = 0
lock = threading.Lock()
t1 = threading.Thread(target=job1)
t2 = threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
print('all done')
Why am I not getting the output I expect?
Python offers no guarantee about exactly when a thread will run. What is apparently happening is that Python starts executing the job1()
thread, and it runs to completion, going through all 10 iterations of its loop, before it starts running the job2()
thread.
There's no way to predict how two threads will be scheduled. For that reason, trusting in any kind of sharing of a global resource like you're doing, without using some kind of controls, like locks or semaphores, or thread-safe classes, is asking for trouble most of the time. For that reason, the locking version of your code, while not giving you the output you want, is a better way to think about having these two threads work together.
BTW, you don't need to call global lock
inside your functions. That would just allow you to point the global lock
reference to a different Lock
object, or to otherwise change the contents of that variable. The Lock
object's behavior won't be affected by that call.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.