简体   繁体   English

如何在多线程情况下使用python线程锁定模块

[英]How can I use python threading lock module in multi-thread case

I was trying to lock a function by using python threading.Lock() , but things not happened as I expected. 我试图通过使用python threading.Lock()锁定函数,但是事情没有按预期发生。

#!/usr/bin/python
# -*- coding:utf-8 -*-

import time
import threading
# mutex = threading.Lock()


def within_mutex():
    print "###########in mutex############"
    n = 0
    while n<5:
        print "waiting ...", n
        n += 1
        time.sleep(1)
    print "##########end mutex############"

def check_thread(lock):
    print "~~~~~~~~~~~in thread~~~~~~~~~~~~"
    print "=====before mutex======", lock.locked()
    with lock:
        print "get mutex, trigger a new thread"
        print "=====in mutex======", lock.locked()
        within_mutex()
    print "=====after mutex======", lock.locked()
    print "~~~~~~~~~~~end thread~~~~~~~~~~~~"

def thread_test(lock):
    if not lock.locked():
        thread1 = threading.Thread(target=check_thread, args=(lock))
        thread1.start()
    print "End thread_test"
    return 11

if __name__ == '__main__':
    lock = threading.Lock()
    t1 = thread_test(lock)
    t2 = thread_test(lock)
    print "t1 = ",t1
    print "t2 = ",t2

As code showed above, I was trying to pass a lock to a thread test function thread_test() , which should trigger a new thread check_thread if lock was not acquired, otherwise should return result (that is 11) immediately. 如上面的代码所示,我试图将锁传递给线程测试函数thread_test() ,如果未获取锁,则该锁应触发新线程check_thread ,否则应立即返回结果(即11)。

In my opinion, in main function, t1 = thread_test(lock) should triggered a new thread, and went into check_thread , and t2 = thread_test(lock) should NOT trigger a new thread, t2 = thread_test(lock) should just return 11 directly. 在我看来,在主函数中, t1 = thread_test(lock)应该触发一个新线程,并进入check_thread ,而t2 = thread_test(lock)不应该触发一个新线程, t2 = thread_test(lock)应该只直接返回11 。

However, two threads were triggered, and I don't know why? 但是,触发了两个线程,我不知道为什么? It seemd that lock.locked() not working or in check_thread function, with lock module not working. 似乎lock.locked()不起作用或在check_thread函数中, with lock模块不起作用。

And, How can I fix this as I only want to trigger ONE thread in this case, How can I get with lock work? 并且,如何解决此问题,因为在这种情况下,我只想触发一个线程,我该如何with lock工作?

result of above code: 以上代码的结果:

End thread_test
~~~~~~~~~~~in thread~~~~~~~~~~~~
=====before mutex====== False
get mutex, trigger a new thread
=====in mutex====== True
###########in mutex############
waiting ... 0
End thread_test
t1 =  11
t2 =  11
~~~~~~~~~~~in thread~~~~~~~~~~~~
=====before mutex====== True
waiting ... 1
waiting ... 2
waiting ... 3
waiting ... 4
##########end mutex############
=====after mutex====== True
~~~~~~~~~~~end thread~~~~~~~~~~~~
get mutex, trigger a new thread
=====in mutex====== True
###########in mutex############
waiting ... 0
waiting ... 1
waiting ... 2
waiting ... 3
waiting ... 4
##########end mutex############
=====after mutex====== False
~~~~~~~~~~~end thread~~~~~~~~~~~~
[Finished in 10.8s]

What is happening: 怎么了:

  1. thread1 says lock is free thread1说锁是免费的
  2. thread2 says lock is free (before thread1 manages to acquire lock) thread2说锁是免费的(在thread1成功获取锁之前)
  3. thread1 enters the with lock , thus acquiring the lock thread1进入with lock ,从而获得了锁
  4. thread2 also enters with lock - it internally tries calling lock.acquire - and the default behaviour is to wait for the lock to be freed up. thread2也with lock输入-它在内部尝试调用lock.acquire并且默认行为是等待释放锁定。 Since lock is already blocked by thread1, thread2 is forced to wait for completion. 由于锁已被线程1阻塞,因此线程2被迫等待完成。
  5. That's why both of them run, even though you try checking if lock.locked() (notice that your current code will sporadically run only one thread) 这就是为什么它们都运行的原因,即使您尝试检查if lock.locked() (请注意,您当前的代码偶尔会仅运行一个线程)

Solution: 解:

Instead of relying on with lock , use explicit lock.acquire(False) and then lock.release() once you're done with execution. 而不是依靠with lock ,使用显式lock.acquire(False) ,然后lock.release()一旦你与执行完成。

Passing the parameter False will change the default behaviour of acquiring locks (see documentation ) 传递参数False将更改获取锁的默认行为(请参阅文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM