Python 线程。如何锁定线程?

我试图理解线程和并发的基本知识。我想要一个简单的情况下,两个线程重复尝试访问一个共享资源。

密码:

import threading


class Thread(threading.Thread):
def __init__(self, t, *args):
threading.Thread.__init__(self, target=t, args=args)
self.start()
count = 0
lock = threading.Lock()


def increment():
global count
lock.acquire()
try:
count += 1
finally:
lock.release()
   

def bye():
while True:
increment()
        

def hello_there():
while True:
increment()


def main():
hello = Thread(hello_there)
goodbye = Thread(bye)
    

while True:
print count


if __name__ == '__main__':
main()

所以,我有两个线程,都试图增加计数器。我认为如果线程‘ A’称为 increment(),那么 lock就会建立起来,阻止‘ B’访问,直到‘ A’被释放。

运行 the 可以清楚地看到情况并非如此。您可以得到所有随机的数据增量。

锁对象到底是如何使用的?

另外,我尝试将锁放入线程函数中,但仍然没有结果。

207701 次浏览

You can see that your locks are pretty much working as you are using them, if you slow down the process and make them block a bit more. You had the right idea, where you surround critical pieces of code with the lock. Here is a small adjustment to your example to show you how each waits on the other to release the lock.

import threading
import time
import inspect


class Thread(threading.Thread):
def __init__(self, t, *args):
threading.Thread.__init__(self, target=t, args=args)
self.start()


count = 0
lock = threading.Lock()


def incre():
global count
caller = inspect.getouterframes(inspect.currentframe())[1][3]
print "Inside %s()" % caller
print "Acquiring lock"
with lock:
print "Lock Acquired"
count += 1
time.sleep(2)


def bye():
while count < 5:
incre()


def hello_there():
while count < 5:
incre()


def main():
hello = Thread(hello_there)
goodbye = Thread(bye)




if __name__ == '__main__':
main()

Sample output:

...
Inside hello_there()
Acquiring lock
Lock Acquired
Inside bye()
Acquiring lock
Lock Acquired
...
import threading


# global variable x
x = 0


def increment():
"""
function to increment global variable x
"""
global x
x += 1


def thread_task():
"""
task for thread
calls increment function 100000 times.
"""
for _ in range(100000):
increment()


def main_task():
global x
# setting global variable x as 0
x = 0


# creating threads
t1 = threading.Thread(target=thread_task)
t2 = threading.Thread(target=thread_task)


# start threads
t1.start()
t2.start()


# wait until threads finish their job
t1.join()
t2.join()


if __name__ == "__main__":
for i in range(10):
main_task()
print("Iteration {0}: x = {1}".format(i,x))