如何正确使用队列和线程

6 python multithreading python-3.x

我是队列和线程的新手,请帮助完成以下代码,在这里我尝试执行函数hd,我需要多次运行该函数,但仅在单次运行完成后

\n
import queue\nimport threading\nimport time\n\nfifo_queue = queue.Queue()\n\ndef hd():\n    print("hi")\n    time.sleep(1)\n    print("done")\n\n\nfor i in range(3):\n    cc = threading.Thread(target=hd)\n    fifo_queue.put(cc)\n    cc.start()\n
Run Code Online (Sandbox Code Playgroud)\n

电流输出

\n
hi\nhi\nhi\ndonedonedone\n
Run Code Online (Sandbox Code Playgroud)\n

预期输出

\n
hi\ndone   \nhi\ndone\nhi\ndone\xe2\x80\x8b\n
Run Code Online (Sandbox Code Playgroud)\n

Eug*_*nij 1

您可以使用信号量来达到您的目的

信号量管理一个内部计数器,该计数器在每次 acquire() 调用时递减,并在每次 release() 调用时递增。计数器永远不会低于零;当 acquire() 发现它为零时,它会阻塞,等待其他线程调用release()。

信号量的默认值是1

类线程.Semaphore(值=1)

所以一次只有一个线程处于活动状态:

import queue
import threading
import time

fifo_queue = queue.Queue()

semaphore = threading.Semaphore()


def hd():
    with semaphore:
        print("hi")
        time.sleep(1)
        print("done")


for i in range(3):
    cc = threading.Thread(target=hd)
    fifo_queue.put(cc)
    cc.start()
Run Code Online (Sandbox Code Playgroud)
hi
done
hi
done
hi
done
Run Code Online (Sandbox Code Playgroud)

正如@user2357112supportsMonica在评论中提到的,RLock将是更安全的选择

线程类.RLock

此类实现可重入锁对象。可重入锁必须由获取它的线程释放。一旦一个线程获得了可重入锁,同一个线程可以再次获得它而不会阻塞;线程每次获取它时都必须释放它一次。

import queue
import threading
import time

fifo_queue = queue.Queue()

lock = threading.RLock()


def hd():
    with lock:
        print("hi")
        time.sleep(1)
        print("done")


for i in range(3):
    cc = threading.Thread(target=hd)
    fifo_queue.put(cc)
    cc.start()

Run Code Online (Sandbox Code Playgroud)

  • 如果您只想使用这样的信号量,那么锁会更合适,“threading.Lock”或“threading.RLock”。(“RLock”通常是最安全的默认值,避免了“Lock”或“Semaphore”可能发生的几类错误。) (2认同)