我正在尝试理解线程和并发的基础知识。我想要一个简单的情况,其中两个线程反复尝试访问一个共享资源。
代码:
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 incre():
global count
lock.acquire()
try:
count += 1
finally:
lock.release()
def bye():
while True:
incre()
def hello_there():
while True:
incre()
def main():
hello = Thread(hello_there)
goodbye = Thread(bye)
while True:
print count
if __name__ == '__main__':
main()
所以,我有两个线程,都试图增加计数器。我认为如果线程'A'被称为incre()
,则lock
将被建立,阻止'B'访问,直到'A'被释放。
运行清楚表明情况并非如此。您将获得所有随机数据竞赛增量。
锁定对象究竟是如何使用的?
编辑,此外,我已经尝试将锁定置于线程函数内部,但仍然没有运气。
答案 0 :(得分:63)
你可以看到你的锁在使用它们时非常有效,如果你减慢了进程并使它们阻塞了一点。你有正确的想法,用锁来包围关键的代码片段。这是对您的示例的一个小调整,以向您展示每个人如何等待释放锁定。
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()
示例输出:
...
Inside hello_there()
Acquiring lock
Lock Acquired
Inside bye()
Acquiring lock
Lock Acquired
...
答案 1 :(得分:-4)
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))