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

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

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

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

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

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

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