【问题标题】:Python - Can semaphore Acquire be unlocked from a specific thread?Python - 可以从特定线程解锁信号量获取吗?
【发布时间】:2019-11-21 09:57:50
【问题描述】:

几周前我出于学习目的开始使用 Python。 我想知道是否可以从特定线程解锁信号量获取。还是有其他工具?

import threading, time

sem = threading.Semaphore

def thread1 (threadname):
    #Code to do
    #Condition thread1
    time.sleep(0.001)
    sem.acquire()
    #Code 1
    sem.release

def thread2 (threadname):
    while (thread1.is_alive() == True):
        if #Condition thread1
            sem.acquire()
            #Code 2
            sem.release

我在线程 1 中的条件正好在 time.sleep 之前(所以线程 2 有时间用 .acquire 阻塞线程 1)。如果我没有那个time.sleep,结果就会不一致。 我现在得到了很好的结果,但我希望我的线程 2 总是在线程 1 开始“Code1”之前开始它的“if”,所以我可以删除那个 time.sleep(0.001) 并获得一致的结果。

你有什么想法吗?

【问题讨论】:

    标签: python multithreading semaphore


    【解决方案1】:

    您要求同步启动行为。为此,您当前使用的信号量不适合。您编码的内容清楚地表明您不关心哪个进程首先运行。这也是处理事物的标准方式,因此如果您需要在另一个线程之前拥有一个线程,则可能需要不同的同步机制。如果我能更多地了解你的潜在愿望,我可以告诉你更多。

    但是,根据您当前的代码,您想要实现的目标将使用第二种机制完成,即在第一个线程甚至尝试获取信号量之前将其阻塞,并且在第二个线程进入信号量后将其释放它的关键代码块,例如。 G。一个threading.Event

    #!/usr/bin/env python3
    
    import threading, time
    
    semaphore = threading.Semaphore()
    event = threading.Event()
    event.clear() 
    
    def action1():
        print("starting thread1")
        time.sleep(0.1)
        print("waiting in thread1 ...")
        event.wait()
        print("woken up in thread1!")
        print("acquiring in thread1 ...")
        semaphore.acquire()
        print("critical in thread 1")
        semaphore.release()
        print("leaving thread1")
    
    def action2():
        print("starting thread2")
        while (threads[0].is_alive()):
            print("acquiring in thread2 ...")
            semaphore.acquire()
            print("critical in thread 2")
            event.set()
            time.sleep(0.1)
            semaphore.release()
            print("released in thread2")
        print("leaving thread2")
    
    threads = [ threading.Thread(target=action1),
                threading.Thread(target=action2) ]
    for thread in threads:
        thread.start()
    for thread in threads:
        thread.join()
    

    但这对我来说似乎很粗糙,容易出错。如果你告诉我们你真正想要达到什么目标,你最初试图解决什么问题,答案可能会得到很大改善。

    【讨论】:

    • 感谢 Alfe,您的解决方案非常适合!
    • 在这种情况下,您可以投票和/或接受答案;但请阅读最后两句话。我仍然觉得给你一个不好的建议(例如,我的代码仅在任意时间后终止,因为 thread2 很容易使 thread1 饿死)。如果您告诉我们您的基本情况是什么,那么建议可能看起来会大不相同。使用线程同步很容易走错方向,而对它所带来的所有风险知之甚少。
    • 好的,就这样吧!我把我的问题告诉了我的老师,他告诉了我和你一样的话,所以我很确定你做得很完美!谢谢
    • 这不是关于我的代表,而是更多关于你没有做出错误决定 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多