Python - 锁定共享资源(多进程)

0 投票
1 回答
1056 浏览
提问于 2025-04-18 18:40

我想发送一个信号来启动第二个过程。就像只有在经过了一段时间后,第二个过程才能开始。这有点像锁定一个共享资源。我该怎么做呢?

这是我的示例代码:

def worker():
    for i in range(1,10):
        if i == 5:
            # send a trigger to start the next event. 
            # Its like 'locking' a shared resource.

def main():
    for i in range(1,100):
        d = multiprocessing.Process(target = worker, args = ())
        d.daemon = True
        d.start()

编辑过的(预期输出)

Process1 loop1
Process1 loop2
Process1 loop3
Process1 loop4
1 2014-08-27 11:45:51.687848 # after this random numbers should get print.
Process2 loop1
Process2 loop2
Process2 loop3
Process2 loop4
Process1 loop5
Process1 loop6
Process1 loop7
Process1 loop8
Process1 loop9
2 2014-08-27 11:45:51.690052
Process2 loop5
Process2 loop6
Process2 loop7
Process2 loop8
Process2 loop9

当前输出

Process1 loop1
Process1 loop2
Process1 loop3
Process1 loop4
1 2014-08-27 11:45:51.687848
Process1 loop5
Process1 loop6
Process1 loop7
Process1 loop8
Process1 loop9
Process2 loop1
Process2 loop2
Process2 loop3
Process2 loop4
2 2014-08-27 11:45:51.690052
Process2 loop5
Process2 loop6
Process2 loop7
Process2 loop8
Process2 loop9

1 个回答

1

我通常喜欢用Queue来控制进程。这种方式更灵活,因为进程可以根据队列中的命令执行不同的操作。

import datetime
import multiprocessing
from multiprocessing import Queue

def worker(work_queue):
    if work_queue.get() == "Start":
            for i in range(1,10):
                if i == 5:
                    # do something
                    print datetime.datetime.now() 

def main():
    worker_queues = {}
    for i in xrange(1, 6):
        q = Queue()
        worker_queues[i] = q # one queue per process here
        d = multiprocessing.Process(target = worker, args = (q,))
        d.daemon = True
        d.start()
    for wq in worker_queues.values():
        wq.put("Start")

if __name__ == "__main__":
    main()

编辑:针对你编辑过的问题,你可以通过在上面的解决方案中添加一个done queue来强制执行顺序。

import datetime
import multiprocessing
from multiprocessing import Queue

def worker(myid, work_queue, done_queue):
    if work_queue.get() == "Start":
        for i in range(1,10):
                if i == 5:
                    # do something
                    print myid, datetime.datetime.now() 
        done_queue.put(myid)

def main():
    worker_queues = {}
    for i in xrange(1, 6): 
        q = Queue()
        done_q = Queue()
        worker_queues[i] = (q, done_q)
        d = multiprocessing.Process(target = worker, args = (i, q, done_q))
        d.daemon = True
        d.start()


    for i in xrange(1, 6): 
        worker_queues[i][0].put("Start")
        if worker_queues[i][1].get():
            # move to next iteration
            pass

if __name__ == "__main__":
    main() 

你可以把这个解决方案理解为进程之间的一种消息传递机制。

撰写回答