2015-12-29 2 views
2

Я следующая структура определена в Python -Как избежать жду завершения потока выполнения - Python

enter image description here

Есть две нити. Каждый поток сканирует ветвь вертикально вниз и печатает ее значение. По достижении конца этой ветви она перемещается на шаг вперед по горизонтальной оси. Например, Thread1 будет печатать a1, a2 и a3. В то же время Thread 2 сканирует b1. Когда оба выполнения завершают нить, Thread 1 перейдет к блоку B, и Thread 2 перейдет к блоку C, чтобы выполнить тот же процесс.

Когда все блоки выполнены, процесс начинается с начала. Я написал сценарий для того же -

def printTags(DevObj): 
    if DevObj == None: 
     return -1 
    TagObj = DevObj.tagPointer 
    while TagObj != None: 
     time.sleep(5) 
     print TagObj.id 
     TagObj = TagObj.nextTag 

import threading, thread 

# temp1 points to Block A. 
# temp2 points to Block B. 

while True: 
    t1 = threading.Thread(target=printTags, args=(temp1,)) 
    t2 = threading.Thread(target=printTags, args=(temp2,)) 
    t1.start() 
    t2.start() 
    t1.join() 
    t2.join() 

    if temp1.nextDevice != None: 
     temp1 = temp1.nextDevice 
    else: 
     temp1 = start.nextDevice 

    if temp2.nextDevice != None: 
     temp2 = temp2.nextDevice 
    else: 
     temp2 = start.nextDevice 

Однако, вы можете увидеть, что когда потоки работают на блок А и В, Thread 1 займет больше времени, чем Thread 2, как он должен напечатать больше значений. Из-за этого Thread 2 остается неиспользованным в течение некоторого времени. Я хочу избежать этого простои. Как я могу это сделать?

+1

есть много вариантов. Как вы хотите, чтобы он себя вел? Например, вы можете иметь цикл while while в потоке, поэтому поток не заканчивается. Вместо этого он продолжается со следующим устройством. Или вы можете удалить 'join' и иметь некоторую другую логику от * снаружи *. – zvone

+0

Я попробую первый вариант. Я попытался удалить join(), но результат не последовал ни одному заказу. Было бы полезно, если бы вы могли рассказать мне, что может быть логикой для этого – apoorvasomani

+0

. Я добавил цикл while while в поток, и он дает мне то, что я хочу. Но безопасно ли запустить бесконечный цикл внутри потока? Предполагается, что они используются только для легких задач. Мне нужна эта нить, чтобы работать в течение долгого времени. Смогут ли потоки справиться с этим потоком? – apoorvasomani

ответ

1

Существуют различные подходы, которые можно предпринять, но я хотел бы отметить два из них:

Во-первых, использовать семафор, этот так близко, как ваш код, но это не является предпочтительным, на самом деле:

from threading import Semaphore 

def printTags(DevObj, s): 
    ... 
    s.release() 
    ... 

import threading, thread 

# temp1 points to Block A. 
# temp2 points to Block B. 


s = Semaphore(0) 
threads = [ 
    threading.Thread(target=printTags, args=(THING_TO_DO,s)) 
    for THING_TO_DO in THINGS_TO_DO 
] 
for t in threads: 
    t.start() 

while True: 
    s.aquire() 
    for t in threads: 
     # give more work 

Более предпочтительным вариантом является использование производителем/потребительское схеме:

from threading import Semaphore 

STOP = object() 

def printTags(queue): 
    while True: 
     thing_to_process = queue.get() 
     if thing_to_process is STOP: 
      return 
     else: 
      #process 

import threading, thread 

# temp1 points to Block A. 
# temp2 points to Block B. 

THREAD_COUNT = 2 
s = Semaphore(0) 
threads = [ 
    threading.Thread(target=printTags, args=(queue,)) 
    for _ in xrange(THREAD_COUNT) 
] 

for thing in things: 
    queue.put(thing) 
for _ in xrange(THREAD_COUNT): 
    queue.put(STOP) 

for t in threads: 
    t.start() 
+0

Разве вы не должны помещать один STOP в поток? Если нет, если вы используете STOP, не следует ли блокировать другие потоки? – tglaria

+0

@tglaria ты совершенно прав, мой плохой. – Andrey

Смежные вопросы