V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
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
yuzhibott
V2EX  ›  Python

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

  •  
  •   yuzhibott · Sep 25, 2017 · 3321 views
    This topic created in 3144 days ago, the information mentioned may be changed or developed.
    13 replies    2017-09-27 14:03:54 +08:00
    yuzhibott
        1
    yuzhibott  
    OP
       Sep 25, 2017
    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
        2
    yuzhibott  
    OP
       Sep 25, 2017
    大概代码如上,不能用 join(),因为实际中是多任务定时处理,每个任务时间不一样
    yuzhibott
        3
    yuzhibott  
    OP
       Sep 25, 2017
    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
        4
    shibingsw  
       Sep 25, 2017
    join 和时间长短有什么关系。。
    yuzhibott
        5
    yuzhibott  
    OP
       Sep 25, 2017
    @shibingsw 多个定时任务啊,每个定时不一样,join 不是只能一个一个线程执行么
    clino
        6
    clino  
       Sep 25, 2017
    "不能用 join(),因为实际中是多任务定时处理,每个任务时间不一样"
    join 做了等待的时候,你如果不用,那么就要自己来实现这个等待的部分,否则不等待就是直接退出了嘛
    scriptB0y
        7
    scriptB0y  
       Sep 25, 2017
    同意 #6

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

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

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

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

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

    那么为什么子进程不会等待非守护线程结束呢??? 我去学习一个
    petelin
        13
    petelin  
       Sep 27, 2017
    @petelin 说的有点问题, 并不是主线程等待子线程都完成在退出(那是 join 干的事), 而是 python 解释器保证 当没有活跃的进程之后才退出(所以主线程先退出, 子线程继续执行, 知道完成 python 进程退出是有可能的).
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3903 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 66ms · UTC 04:24 · PVG 12:24 · LAX 21:24 · JFK 00:24
    ♥ Do have faith in what you're doing.