在Python中同步多个线程

6 投票
3 回答
8215 浏览
提问于 2025-04-15 11:43

我遇到了一个问题,我需要让x个线程等到它们都到达一个同步点。我的解决方案是使用下面的synchronise方法,每个线程在需要同步的时候都会调用这个方法。

有没有更好的方法来做到这一点呢?

thread_count = 0
semaphore = threading.Semaphore()
event = threading.Event()

def synchronise(count):
    """ All calls to this method will block until the last (count) call is made """
    with semaphore:
        thread_count += 1
        if thread_count == count:
            event.set()

    event.wait()

def threaded_function():
    # Do something

    # Block until 4 threads have reached this point
    synchronise(4)

    # Continue doing something else

3 个回答

2

你想要的功能叫做“屏障”。(不幸的是,这个词在讨论线程时有两个意思。所以如果你在网上搜索,记得忽略那些讲“内存屏障”的文章——那是完全不同的东西)。

你的代码看起来很不错——简单又安全。

我没有找到任何“标准”的Python屏障实现,所以我建议你继续使用你的代码。

4

请注意,从 Python 3.2 开始,Barrier 这个功能已经被实现了,具体可以查看官方文档

下面是使用 Barrier 的一个例子:

from threading import Barrier, Thread

def get_votes(site):
    ballots = conduct_election(site)
    all_polls_closed.wait()        # do not count until all polls are closed
    totals = summarize(ballots)
    publish(site, totals)

all_polls_closed = Barrier(len(sites))
for site in sites:
    Thread(target=get_votes, args=(site,)).start()
2

有很多方法可以让线程同步,真的很多。

除了直接使用同步,你还可以尝试以下几种方法。

  1. 把你的任务分成两个步骤,在同步点前后进行。先让线程执行同步前的步骤。然后用“join”来等待所有线程完成第一步。接着再启动新的线程来执行同步后的步骤。我个人更喜欢这种方法,而不是直接同步。

  2. 创建一个队列;获取一个同步锁。启动所有线程。每个线程在队列中放入一个条目,然后等待同步锁。主线程则在一个循环中从队列中取出条目。当所有线程都在队列中放入了条目后,主线程就释放同步锁。这样其他线程就可以自由运行了。

还有很多进程间通信(IPC)技术,这些都可以用来实现线程同步。

撰写回答