Создание одноэлементного потока. Как создать не более одного экземпляра потока одновременно - PullRequest
2 голосов
/ 16 февраля 2012

Я ищу класс (подкласс от Threading.Thread), который инициализируется и запускается из нескольких мест в программе.Чего я хочу избежать, так это если поток уже запущен откуда-то еще, если другое место в программе пытается его запустить

t= somemodule.TheThread(some,args)
t.start()

, программа может продолжаться (но поток запускается, только если тот же потокне работает ни здесь, ни где-либо еще).

Я могу придумать несколько не очень элегантных способов добиться этого с помощью установки флагов, но должен быть хороший способ справиться с этим.Я посмотрел на шаблоны синглтонного типа с декораторами или с переопределением new , но главная проблема в том, что если я сохраню тот же экземпляр, то вы не сможете (насколько мне известно) вызывать start несколько раз, дажепоток завершен.

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

У кого-нибудь есть идеи?

Ответы [ 3 ]

6 голосов
/ 16 февраля 2012

Вы должны использовать функцию для создания и запуска потока, и эта функция может использовать свою собственную бухгалтерию, чтобы узнать, был ли поток уже запущен или нет.Не забудьте сделать эту бухгалтерию безопасной для потоков!

Попытка убедить вызывающего абонента в том, что он создает и запускает поток, а может, и нет, доставляет больше хлопот, чем оно того стоит.Инкапсуляция этой обычной операции в функцию - хорошая идея в любом случае, она дает вам необходимый контроль.

0 голосов
/ 16 февраля 2012

Запустите поток при запуске приложения и дождитесь события.Если событие установлено, поток выполняет свою работу, сбрасывает событие и ждет его снова.Как только какой-то другой поток «запускает» поток цикла, устанавливая событие, любое количество других потоков может вызвать «set», но ничего не произойдет, пока поток цикла не выполнит свою работу, не очистит событие и снова не будет ждать.

Нет микроуправления потоками, нет возможности наличия более одного экземпляра потока, нет небезопасности потока, нет флагов, нет сомнительной проверки состояния потока.

Есть небольшое окно между циклом- завершить свою работу и очистить событие, когда набор из другого потока будет проигнорирован.Такую неопределенность трудно устранить с помощью выбранного вами дизайна.Вы можете использовать семафор вместо события и использовать цикл получения (ложь) в верхней части, чтобы проверить, был ли передан сигнал семафору, а также убедиться, что его счет снова равен нулю.Если семафор был послан, поток может снова запустить свою работу.Если семафор не был сигнализирован, его можно ждать до тех пор, пока он не появится.

0 голосов
/ 16 февраля 2012

Один простой способ проверить, жив ли поток somemodule.TheThread, выглядит следующим образом:

any(isinstance(thread, somemodule.TheThread)
    for thread in threading.enumerate())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...