Синхронизация нескольких потоков в Python - PullRequest
6 голосов
/ 20 мая 2009

У меня проблема с тем, что мне нужно 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 голосов
/ 29 августа 2014

Обратите внимание, что барьер был реализован с Python 3.2

Пример использования барьеров:

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 голосов
/ 20 мая 2009

Функциональность, которую вы хотите, называется " барьер ". (К сожалению, этот термин имеет два значения, когда речь идет о многопоточности. Поэтому, если вы Google , просто игнорируйте статьи, в которых говорится о " барьерах памяти " - это совсем другое) *

Ваш код выглядит вполне разумно - он прост и безопасен.

Я не смог найти никаких "стандартных" реализаций барьеров для Python, поэтому я предлагаю вам продолжать использовать ваш код.

1 голос
/ 20 мая 2009

Есть много способов синхронизации потоков. Многие.

Помимо синхронизации вы можете выполнять следующие действия:

  1. Разбейте свои задачи на два шага вокруг точки синхронизации. Запустите потоки, выполнив шаг предварительной синхронизации. Затем используйте «join», чтобы дождаться завершения всех потоков. Шаг 1. Запустите новые темы, выполнив шаг после синхронизации. Я предпочитаю это, а не синхронизировать.

  2. Создать очередь; получить блокировку синхронизации. Начать все темы. Каждый поток помещает запись в очередь и ожидает блокировки синхронизации. «Основной» поток находится в цикле, исключая элементы из очереди. Когда все потоки помещают элемент в очередь, «основной» поток снимает блокировку синхронизации. Все остальные темы теперь могут запускаться снова.

Существует ряд методов межпроцессного взаимодействия (IPC), каждый из которых можно использовать для синхронизации потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...