[python] 파이썬 스레딩에서 join ()을 사용하는 것은 무엇입니까?

나는 파이썬 스레딩을 공부하고 있었고 건너왔다 join().

저자는 스레드가 데몬 모드 인 경우 join()주 스레드가 종료되기 전에 스레드가 스스로 완료되도록 사용해야 한다고 말했습니다.

그러나 나는 또한 사용 그를 보았다 t.join()비록 t아니었다daemon

예제 코드는 다음과 같습니다

import threading
import time
import logging

logging.basicConfig(level=logging.DEBUG,
                    format='(%(threadName)-10s) %(message)s',
                    )

def daemon():
    logging.debug('Starting')
    time.sleep(2)
    logging.debug('Exiting')

d = threading.Thread(name='daemon', target=daemon)
d.setDaemon(True)

def non_daemon():
    logging.debug('Starting')
    logging.debug('Exiting')

t = threading.Thread(name='non-daemon', target=non_daemon)

d.start()
t.start()

d.join()
t.join()

t.join()데몬이 아니기 때문에 무엇을 사용하는지 알 수 없으며 제거해도 아무런 변화가 없습니다.



답변

메커니즘을 설명하기 위해 다소 어색한 예술 작품 : join()아마도 메인 스레드에 의해 호출됩니다. 다른 스레드에서 호출 할 수도 있지만 다이어그램을 불필요하게 복잡하게 만듭니다.

join호출은 주 스레드의 트랙에 배치해야하지만 스레드 관계를 표현하고 가능한 한 간단하게 유지하려면 대신 자식 스레드에 배치하도록 선택합니다.

without join:
+---+---+------------------                     main-thread
    |   |
    |   +...........                            child-thread(short)
    +..................................         child-thread(long)

with join
+---+---+------------------***********+###      main-thread
    |   |                             |
    |   +...........join()            |         child-thread(short)
    +......................join()......         child-thread(long)

with join and daemon thread
+-+--+---+------------------***********+###     parent-thread
  |  |   |                             |
  |  |   +...........join()            |        child-thread(short)
  |  +......................join()......        child-thread(long)
  +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,     child-thread(long + daemonized)

'-' main-thread/parent-thread/main-program execution
'.' child-thread execution
'#' optional parent-thread execution after join()-blocked parent-thread could
    continue
'*' main-thread 'sleeping' in join-method, waiting for child-thread to finish
',' daemonized thread - 'ignores' lifetime of other threads;
    terminates when main-programs exits; is normally meant for
    join-independent tasks

따라서 변경 사항이 표시되지 않는 이유는 메인 스레드가 join. join메인 스레드의 실행 흐름과 관련이 있다고 말할 수 있습니다.

예를 들어, 여러 페이지를 동시에 다운로드하여 하나의 큰 페이지로 연결하려는 경우 스레드를 사용하여 동시 다운로드를 시작할 수 있지만 단일 페이지를 조립하기 전에 마지막 페이지 / 스레드가 완료 될 때까지 기다려야합니다 많은 중. 그때 사용 join()합니다.


답변

문서 에서 바로

join ([timeout]) 스레드가 종료 될 때까지 기다립니다. 이것은 join () 메소드가 호출 된 스레드가 정상적으로 또는 처리되지 않은 예외를 통해 종료 될 때까지 또는 선택적 시간 종료가 발생할 때까지 호출 스레드를 차단합니다.

이 수단 메인 쓰레드있는 급부상 그 td에 대한 대기 t가 끝날 때까지 완료합니다.

프로그램에서 사용하는 논리에 따라 메인 스레드가 계속되기 전에 스레드가 완료 될 때까지 기다릴 수 있습니다.

또한 문서에서 :

스레드는 “데몬 스레드”로 표시 될 수 있습니다. 이 플래그의 의미는 데몬 스레드 만 남으면 전체 Python 프로그램이 종료된다는 것입니다.

간단한 예를 들면 다음과 같습니다.

def non_daemon():
    time.sleep(5)
    print 'Test non-daemon'

t = threading.Thread(name='non-daemon', target=non_daemon)

t.start()

어느 것으로 마무리 :

print 'Test one'
t.join()
print 'Test two'

출력됩니다 :

Test one
Test non-daemon
Test two

여기서 마스터 스레드는 t스레드가 print두 번째 호출 될 때까지 스레드가 완료 될 때까지 명시 적으로 대기합니다 .

또는 우리가 이것을 가지고 있다면 :

print 'Test one'
print 'Test two'
t.join()

이 결과를 얻을 수 있습니다 :

Test one
Test two
Test non-daemon

여기서 우리는 메인 스레드에서 작업을 수행 한 다음 t스레드가 완료 될 때까지 기다립니다 . 이 경우 명시 적 결합을 제거 할 수도 t.join()있으며 프로그램은 암시 적 t으로 완료를 기다립니다 .


답변

이 글에 감사드립니다-나에게 많은 도움이되었습니다.

오늘 .join ()에 대해 배웠습니다.

이 스레드는 병렬로 실행됩니다.

d.start()
t.start()
d.join()
t.join()

그리고 이들은 순차적으로 실행됩니다 (원하는 것이 아님).

d.start()
d.join()
t.start()
t.join()

특히, 나는 영리하고 깔끔하게 노력했습니다.

class Kiki(threading.Thread):
    def __init__(self, time):
        super(Kiki, self).__init__()
        self.time = time
        self.start()
        self.join()

작동합니다! 그러나 순차적으로 실행됩니다. self.start ()를 __ init __에 넣을 수 있지만 self.join ()을 넣을 수는 없습니다. 모든 스레드가 시작된 후에 수행해야합니다 .

join ()은 메인 스레드가 스레드가 완료 될 때까지 대기하게하는 원인입니다. 그렇지 않으면 스레드가 자체적으로 실행됩니다.

따라서 메인 스레드에서 join ()을 “hold”로 생각하는 한 가지 방법은 메인 스레드를 계속하기 전에 스레드를 스레드 해제하고 메인 스레드에서 순차적으로 실행하는 것입니다. 메인 스레드가 앞으로 이동하기 전에 스레드가 완료되었는지 확인합니다. join ()을 호출하기 전에 스레드가 이미 완료된 경우 괜찮습니다. 기본 스레드는 join ()이 호출 될 때 즉시 해제됩니다.

사실, 메인 스레드가 스레드 d가 t.join ()으로 이동하기 전에 완료 될 때까지 d.join ()에서 대기합니다.

실제로 매우 명확하게 다음 코드를 고려하십시오.

import threading
import time

class Kiki(threading.Thread):
    def __init__(self, time):
        super(Kiki, self).__init__()
        self.time = time
        self.start()

    def run(self):
        print self.time, " seconds start!"
        for i in range(0,self.time):
            time.sleep(1)
            print "1 sec of ", self.time
        print self.time, " seconds finished!"


t1 = Kiki(3)
t2 = Kiki(2)
t3 = Kiki(1)
t1.join()
print "t1.join() finished"
t2.join()
print "t2.join() finished"
t3.join()
print "t3.join() finished"

이 출력을 생성합니다 (인쇄 문이 서로 스레드되는 방식에 유의하십시오).

$ python test_thread.py
32   seconds start! seconds start!1

 seconds start!
1 sec of  1
 1 sec of 1  seconds finished!
 21 sec of
3
1 sec of  3
1 sec of  2
2  seconds finished!
1 sec of  3
3  seconds finished!
t1.join() finished
t2.join() finished
t3.join() finished
$ 

t1.join ()이 메인 스레드를 잡고 있습니다. t1.join ()이 끝나기 전에 3 개의 스레드가 모두 완료되고 메인 스레드가 인쇄를 실행 한 다음 t2.join ()을 인쇄 한 다음 t3.join ()을 인쇄하고 인쇄합니다.

정정을 환영합니다. 또한 스레딩을 처음 사용합니다.

(참고 : 관심이 있으시면 DrinkBot 용 코드를 작성 중이며 성분 펌프를 순차적으로 실행하지 않고 동시에 실행하기 위해 스레딩이 필요합니다. 각 음료를 기다리는 시간이 짧습니다.)


답변

join () 메소드

join () 메소드가 호출 된 스레드가 종료 될 때까지 호출 스레드를 차단합니다.

출처 : http://docs.python.org/2/library/threading.html


답변

간단한 이해,

with join-통역사가 프로세스가 완료 되거나 종료 될 때까지 기다립니다.

>>> from threading import Thread
>>> import time
>>> def sam():
...   print 'started'
...   time.sleep(10)
...   print 'waiting for 10sec'
...
>>> t = Thread(target=sam)
>>> t.start()
started

>>> t.join() # with join interpreter will wait until your process get completed or terminated
done?   # this line printed after thread execution stopped i.e after 10sec
waiting for 10sec
>>> done?

join-interpreter 없이는 프로세스가 종료 될 때까지 기다리지 않습니다 .

>>> t = Thread(target=sam)
>>> t.start()
started
>>> print 'yes done' #without join interpreter wont wait until process get terminated
yes done
>>> waiting for 10sec


답변

join(t)비 데몬 스레드와 데몬 스레드 모두에 대해 기능을 수행 할 때 기본 스레드 (또는 기본 프로세스)는 t몇 초 동안 기다린 다음 자체 프로세스에서 계속 작업 할 수 있습니다. t대기 시간 (초) 동안 두 하위 스레드 모두 텍스트 인쇄와 같이 수행 할 수있는 작업을 수행해야합니다. 애프터 t초, 비 데몬 스레드가 여전히 작업을 완료하지 않았고, 주요 프로세스가 작업을 완료 한 후 여전히 그것을 끝낼 수 있지만, 데몬 스레드, 그냥 그 기회의 창을 놓친 경우. 그러나 파이썬 프로그램이 종료되면 결국 죽을 것입니다. 문제가 있으면 수정 해주세요.


답변

파이썬 3.x에서 join ()은 메인 스레드와 스레드를 결합하는 데 사용됩니다.

#1 - Without Join():
import threading
import time
def loiter():
    print('You are loitering!')
    time.sleep(5)
    print('You are not loitering anymore!')

t1 = threading.Thread(target = loiter)
t1.start()
print('Hey, I do not want to loiter!')
'''
Output without join()-->
You are loitering!
Hey, I do not want to loiter!
You are not loitering anymore! #After 5 seconds --> This statement will be printed

'''
#2 - With Join():
import threading
import time
def loiter():
    print('You are loitering!')
    time.sleep(5)
    print('You are not loitering anymore!')

t1 = threading.Thread(target = loiter)
t1.start()
t1.join()
print('Hey, I do not want to loiter!')

'''
Output with join() -->
You are loitering!
You are not loitering anymore! #After 5 seconds --> This statement will be printed
Hey, I do not want to loiter!

'''