programing tip

파이썬 스레딩에서 join () 사용은 무엇입니까

itbloger 2020. 6. 3. 21:28
반응형

파이썬 스레딩에서 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 ()을 "홀드"로 생각하는 한 가지 방법은 메인 스레드를 계속하기 전에 스레드를 스레드 해제하고 메인 스레드에서 순차적으로 실행하는 것입니다. 메인 스레드가 앞으로 이동하기 전에 스레드가 완료되었는지 확인합니다. 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
$ 

The t1.join() is holding up the main thread. All three threads complete before the t1.join() finishes and the main thread moves on to execute the print then t2.join() then print then t3.join() then print.

Corrections welcome. I'm also new to threading.

(Note: in case you're interested, I'm writing code for a DrinkBot, and I need threading to run the ingredient pumps concurrently rather than sequentially -- less time to wait for each drink.)


The method join()

blocks the calling thread until the thread whose join() method is called is terminated.

Source : http://docs.python.org/2/library/threading.html


Simple Understand,

with join - interpreter will wait until your process get completed or terminated

>>> 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?

without join - interpreter wont wait until process get terminated,

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

When making join(t) function for both non-daemon thread and daemon thread, the main thread (or main process) should wait t seconds, then can go further to work on its own process. During the t seconds waiting time, both of the children threads should do what they can do, such as printing out some text. After the t seconds, if non-daemon thread still didn't finish its job, and it still can finish it after the main process finishes its job, but for daemon thread, it just missed its opportunity window. However, it will eventually die after the python program exits. Please correct me if there is something wrong.


In python 3.x join() is used to join a thread with the main thread i.e. when join() is used for a particular thread the main thread will stop executing until the execution of joined thread is complete.

#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! 

'''

This example demonstrate the .join() action:

import threading
import time

def threaded_worker():
    for r in range(10):
        print('Other: ', r)
        time.sleep(2)

thread_ = threading.Timer(1, threaded_worker)
thread_.daemon = True  # If the main thread kills, this thread will be killed too. 
thread_.start()

flag = True

for i in range(10):
    print('Main: ', i)
    time.sleep(2)
    if flag and i > 4:
        print(
            '''
            Threaded_worker() joined to the main thread. 
            Now we have a sequential behavior instead of concurrency.
            ''')
        thread_.join()
        flag = False

Out:

Main:  0
Other:  0
Main:  1
Other:  1
Main:  2
Other:  2
Main:  3
Other:  3
Main:  4
Other:  4
Main:  5
Other:  5

            Threaded_worker() joined to the main thread. 
            Now we have a sequential behavior instead of concurrency.

Other:  6
Other:  7
Other:  8
Other:  9
Main:  6
Main:  7
Main:  8
Main:  9

"What's the use of using join()?" you say. Really, it's the same answer as "what's the use of closing files, since python and the OS will close my file for me when my program exits?".

It's simply a matter of good programming. You should join() your threads at the point in the code that the thread should not be running anymore, either because you positively have to ensure the thread is not running to interfere with your own code, or that you want to behave correctly in a larger system.

You might say "I don't want my code to delay giving an answer" just because of the additional time that the join() might require. This may be perfectly valid in some scenarios, but you now need to take into account that your code is "leaving cruft around for python and the OS to clean up". If you do this for performance reasons, I strongly encourage you to document that behavior. This is especially true if you're building a library/package that others are expected to utilize.

There's no reason to not join(), other than performance reasons, and I would argue that your code does not need to perform that well.

참고URL : https://stackoverflow.com/questions/15085348/what-is-the-use-of-join-in-python-threading

반응형