在异步进程下创建线程,线程执行循环任务,为什么线程还没执行完任务进程就退出了?

2017-09-25 17:33:29 +08:00
 yuzhibott
2469 次点击
所在节点    Python
13 条回复
yuzhibott
2017-09-25 17:34:32 +08:00
num = 0

def test1(*data):
global num
i = data[0]
while True:
if num == 10:
num = 0
break
print(i)
num += 1
time.sleep(2)

def test2(*data):
i = data[0]
threading.Thread(target=test1, args=(i,)).start()
print("done")

pool = multiprocessing.Pool(processes=5)
for j in range(2):
pool.apply_async(test2, (j,))
yuzhibott
2017-09-25 17:35:50 +08:00
大概代码如上,不能用 join(),因为实际中是多任务定时处理,每个任务时间不一样
yuzhibott
2017-09-25 17:50:27 +08:00
num = 0

def test1(*data):
global num
i = data[0]
while True:
if num == 10:
num = 0
break
print(i)
num += 1
time.sleep(2)

def test2(*data):
i = data[0]
threading.Thread(target=test1, args=(i,)).start()
print("done")

pool = multiprocessing.Pool(processes=5)
for j in range(2):
pool.apply_async(test2, (j,))
shibingsw
2017-09-25 17:57:14 +08:00
join 和时间长短有什么关系。。
yuzhibott
2017-09-25 17:59:57 +08:00
@shibingsw 多个定时任务啊,每个定时不一样,join 不是只能一个一个线程执行么
clino
2017-09-25 18:00:30 +08:00
"不能用 join(),因为实际中是多任务定时处理,每个任务时间不一样"
join 做了等待的时候,你如果不用,那么就要自己来实现这个等待的部分,否则不等待就是直接退出了嘛
scriptB0y
2017-09-25 18:02:27 +08:00
同意 #6

join 阻塞主线程,如果不想用 join 的话,必须让主线程的运行时间最长,否则主线程跑完进程结束
shibingsw
2017-09-25 19:33:37 +08:00
@yuzhibott 你把所有线程都启动了,然后再一个一个的 join 不就行了?要是还不理解你应该去看看书了~
ryd994
2017-09-26 05:07:54 +08:00
不能用 join,就不能检查 is_alive 了?
再说了,谁说不能 join ?一个一个 join 过去就行,全 join 完退出
justou
2017-09-26 08:51:32 +08:00
如果不是创建的后台线程, 不在主线程 join 的话, 主线程结束, 子线程就强制退出了;
如果是后台线程, 主线程结束后, 子线程自个跑自个的:

from threading import Thread
from time import sleep

def work():
sleep(5)
with open("test.txt", 'w') as fout:
pass

if __name__ == "__main__":
t = Thread(target=work)
t.setDaemon(True)
t.start()
petelin
2017-09-27 13:25:01 +08:00
@justou 后台线程作用是, 当主线程退出的时候, 不用管他们(那他们能欢快的在后台运行吗? 看进程, 进程都退出了,直接被干掉). 反而非后台进程, 主进程即使不 join, 退出之前也要等子线程结束.

所以还是要学习一个.
petelin
2017-09-27 13:36:56 +08:00
那么这段代码问题是, 主进程跑完之后, 所有子进程都被干掉了.无论你子进程在干什么, 直接被干掉.

所有需要在主进程加一段代码
pool.close()
pool.join()

这样看起来就完了, 主进程会等待子进程完成, 而子进程会等待线程完成

可是子进程不会等待线程完成, 所以
t.start()
t.join()

那么为什么子进程不会等待非守护线程结束呢??? 我去学习一个
petelin
2017-09-27 14:03:54 +08:00
@petelin 说的有点问题, 并不是主线程等待子线程都完成在退出(那是 join 干的事), 而是 python 解释器保证 当没有活跃的进程之后才退出(所以主线程先退出, 子线程继续执行, 知道完成 python 进程退出是有可能的).

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/393501

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX