Многопоточность Python: нужен совет для синхронизации 2 потоков с помощью условной переменной - PullRequest
0 голосов
/ 03 апреля 2012

Я знаю только основные концепции многопоточности, и в настоящее время я сталкиваюсь с ситуацией, которая требует некоторой помощи.

У меня есть две задачи, которые нужно выполнить, и обе должны выполняться непрерывно.Дело в том, что вторая задача должна запускаться только после того, как первый поток сначала выполнил несколько заданий.Прямо сейчас два класса потока выглядят примерно так:

finished = False # shared flag 

class first(threading.Thread):
    def __init__(self, cond, finished):
        threading.Thread.__init__(self)
        self.cond = cond
        self.finished = finished

    def run(self):
        self.cond.aquire()
        do_something()
        self.finished = True #change the flag
        self.cond.notify()
        self.cond.release()
        do_something_else()


class second(threading.Thread):
    def __init__(self, cond, finished):
        threading.Thread.__init__(self)
        self.cond = cond
        self.finished = finished

    def run(self):
        self.cond.aquire()
        while self.finished == False:
            self.cond.wait()
        self.cond.release()
        do_something()

Однако факт заключается в том, что программа по-прежнему выполняется случайным образом независимо от wait () и notify ().Кто-нибудь может мне помочь с этим вопросом?Спасибо.

Ответы [ 2 ]

3 голосов
/ 03 апреля 2012

self.finished в class first является копией значения глобального finished, а не ссылкой на него, поэтому он не имеет прямого отношения к self.finished из class second.

Вероятно, вам следует создать глобальный объект Queue (который предназначен для использования с модулем threading). Пусть оба класса ссылаются на очередь, и пусть первый поток записывает сигнал о прохождении в очередь, а второй блок - до тех пор, пока не будет считано разрешение.

1 голос
/ 03 апреля 2012

Вы можете вообще избежать синхронизации. Используйте 3 темы вместо 2.

Поток 1a «выполняет какую-то работу» и завершается. Поток 1b начинается там, где закончился 1a, и Поток 2 запускается независимо.

(Также я предполагаю, что вы знаете, что вы не можете эффективно разделять ЦП с потоками Python; они хороши только для параллельного ожидания ввода-вывода. Когда вам требуется параллелизация с ЦП, вы используете многопроцессорность .)

...