我在学习python线程时遇到了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()是一个自然的阻塞调用,用于调用连接的线程在被调用的线程终止后继续执行。

如果一个python程序没有加入其他线程,python解释器仍然会代表它加入非守护线程。

其他回答

谢谢你的这篇文章——它也帮了我很多。

我今天学了一些关于.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结束,然后才移动到t.t 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"

它产生这样的输出(注意print语句是如何相互衔接的)。

$ 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()结束之前,所有三个线程都完成了,主线程继续执行打印,然后t2.join(),然后打印,然后t3.join(),然后打印。

修正的欢迎。我也是线程的新手。

(注意:如果你感兴趣的话,我正在为DrinkBot编写代码,我需要线程来并发地运行配料泵,而不是按顺序运行——这样就可以减少等待每种饮料的时间。)

在python中3。X join()用于连接线程与主线程,即当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! 

'''

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.

使用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 -解释器不会等待进程被终止,

>>> 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()操作:

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 is killed, this thread will be killed as well. 
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