Python线程:加入一个已死的线程

5
如果我在已经完成的线程上调用join()会发生什么?
例如:
import threading
import time

def fn():
    time.sleep(1)

t = threading.Thread(target=fn)
t.start()

time.sleep(2)
t.join()

在这个问题上,文档似乎没有提供任何明确的信息。


该调用是非阻塞的,并且会跳过到结尾/下一条指令。 - Jean-François Fabre
在那种情况下,它只是立即返回。 - Fred Larson
为什么不试一试自己呢 :) - Nimish Bansal
@NimishBansal,是的,尝试并不太难。我只是想知道这种行为是否有官方定义,以便我每次都可以依赖它。正如其他人指出的那样,我假设调用会立即返回,但我希望文档能更加明确。 - JohannB
关于死线程,我更想问如何重新启动死线程,因为thread.start()会引发异常 :) - Nimish Bansal
1个回答

6

引用您提供的文档:

join: 等待线程终止...

所以如果线程已经终止,当然会立即退出。

文档的另一个地方也有类似的描述:

此操作将阻塞,直到线程终止。

所以如果线程已经终止,该操作不会阻塞。

join方法是提供调用者与线程同步的一种方式。在join退出后,保证线程已结束。如果在线程调用join时已经结束,则不做任何事情。

这在Python源代码中得到了确认(该函数从join()被调用):

def _wait_for_tstate_lock(self, block=True, timeout=-1):
    # Issue #18808: wait for the thread state to be gone.
    # At the end of the thread's life, after all knowledge of the thread
    # is removed from C data structures, C code releases our _tstate_lock.
    # This method passes its arguments to _tstate_lock.acquire().
    # If the lock is acquired, the C code is done, and self._stop() is
    # called.  That sets ._is_stopped to True, and ._tstate_lock to None.
    lock = self._tstate_lock
    if lock is None:  # already determined that the C code is done
        assert self._is_stopped   # we see that we don't wait for anything here
    elif lock.acquire(block, timeout):
        lock.release()
        self._stop()

7
如果文档能更加明确,就像pthread_join的man页面那样:"如果该线程已经终止,则pthread_join()会立即返回",那就太好了。 - Fred Larson
我的意思是,如果你想要扯细节的话,在调用 join() 后,线程实际上并没有终止(因为它已经终止了),这将意味着 join() 会一直阻塞。 - JohannB
1
系统检查线程是否仍在运行。如果不是,则立即退出。否则将会出现死锁。很容易避免死锁,所以系统会避免它。 - Jean-François Fabre
1
JohannB已经掌握了这个。文档没有说明如果线程已经死亡会发生什么。它们都假设线程将终止。一个死亡的线程永远不会终止,因此说“它永远不会返回”或“行为未定义”同样有效。后者甚至无法通过测试证明是错误的,因为它可能只是巧合地通过了测试。 - Steve Carter
如果线程已经终止,那么“join”不会永远阻塞,这是没有意义的。 - Jean-François Fabre
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接