首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
V2EX  ›  Python

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

  •  
  •   yuzhibott · 359 天前 · 1290 次点击
    这是一个创建于 359 天前的主题,其中的信息可能已经有所发展或是发生改变。
    13 回复  |  直到 2017-09-27 14:03:54 +08:00
        1
    yuzhibott   359 天前
    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,))
        2
    yuzhibott   359 天前
    大概代码如上,不能用 join(),因为实际中是多任务定时处理,每个任务时间不一样
        3
    yuzhibott   359 天前
    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,))
        4
    shibingsw   359 天前
    join 和时间长短有什么关系。。
        5
    yuzhibott   359 天前
    @shibingsw 多个定时任务啊,每个定时不一样,join 不是只能一个一个线程执行么
        6
    clino   359 天前
    "不能用 join(),因为实际中是多任务定时处理,每个任务时间不一样"
    join 做了等待的时候,你如果不用,那么就要自己来实现这个等待的部分,否则不等待就是直接退出了嘛
        7
    scriptB0y   359 天前
    同意 #6

    join 阻塞主线程,如果不想用 join 的话,必须让主线程的运行时间最长,否则主线程跑完进程结束
        8
    shibingsw   359 天前
    @yuzhibott 你把所有线程都启动了,然后再一个一个的 join 不就行了?要是还不理解你应该去看看书了~
        9
    ryd994   359 天前
    不能用 join,就不能检查 is_alive 了?
    再说了,谁说不能 join ?一个一个 join 过去就行,全 join 完退出
        10
    justou   358 天前
    如果不是创建的后台线程, 不在主线程 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()
        11
    petelin   357 天前
    @justou 后台线程作用是, 当主线程退出的时候, 不用管他们(那他们能欢快的在后台运行吗? 看进程, 进程都退出了,直接被干掉). 反而非后台进程, 主进程即使不 join, 退出之前也要等子线程结束.

    所以还是要学习一个.
        12
    petelin   357 天前
    那么这段代码问题是, 主进程跑完之后, 所有子进程都被干掉了.无论你子进程在干什么, 直接被干掉.

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

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

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

    那么为什么子进程不会等待非守护线程结束呢??? 我去学习一个
        13
    petelin   357 天前
    @petelin 说的有点问题, 并不是主线程等待子线程都完成在退出(那是 join 干的事), 而是 python 解释器保证 当没有活跃的进程之后才退出(所以主线程先退出, 子线程继续执行, 知道完成 python 进程退出是有可能的).
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   654 人在线   最高记录 3762   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 17ms · UTC 21:25 · PVG 05:25 · LAX 14:25 · JFK 17:25
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1