Python线程。如何锁定线程?

时间:2021-04-09 21:01:28

I'm trying to understand the basics of threading and concurrency. I want a simple case where two threads repeatedly try to access one shared resource.

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

The code:

代码:

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()

So, I have two threads, both trying to increment the counter. I thought that if thread 'A' called incre(), the lock would be established, preventing 'B' from accessing until 'A' has released.

所以,我有两个线程,都试图增加计数器。我认为如果线程'A'调用increment(),则会建立锁定,阻止'B'访问,直到'A'释放。

Running the makes it clear that this is not the case. You get all of the random data race-ish increments.

运行时清楚地表明情况并非如此。您将获得所有随机数据竞赛增量。

How exactly is the lock object used?

锁对象究竟是如何使用的?

Edit, Additionally, I've tried putting the locks inside of the thread functions, but still no luck.

编辑,另外,我已经尝试将锁定置于线程函数内部,但仍然没有运气。

1 个解决方案

#1


51  

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
...

#1


51  

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
...