V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
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
longchisihai
V2EX  ›  Python

请教主线程不结束时怎么结束子线程 ?

  •  
  •   longchisihai · 2016-09-16 16:18:40 +08:00 · 3425 次点击
    这是一个创建于 3019 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我有一个主线程,不断的去循环判断某个目录是否有文件,一旦有文件,则创建多线程把这些文件全部挪到另外的地方。而目前存在的问题是,由于这个主线程是永远不退出的,导致创建的子线程越来越多,子线程占用的内存也越来越多,有什么好的办法结束子线程吗?
    16 条回复    2016-09-17 19:32:12 +08:00
    pagxir
        1
    pagxir  
       2016-09-16 16:21:37 +08:00 via Android
    需要做子线程的 join/detach 。
    wizardforcel
        2
    wizardforcel  
       2016-09-16 16:36:32 +08:00 via Android
    如果不需要控制子线程,创建之后应该立即 detach 。
    longchisihai
        3
    longchisihai  
    OP
       2016-09-16 16:49:24 +08:00
    @wizardforcel
    threading 模块没有 detach 方法呀,怎么 detach 呢?
    raysonx
        4
    raysonx  
       2016-09-16 16:49:36 +08:00 via iPad   ❤️ 1
    我从另外的角度谈一谈这个问题。
    1.理想的方式是子线程完成任务后主动退出,如果子线程工作期间被不明真相的主线程强制杀死,可能会产生无法预知的行为。
    2.主线程不断创建子线程不是一个好的策略,因为机器的硬件资源有限,同时创建大量线程反而降低运行效率。建议维护一份任务队列和线程池,由线程池中的线程从任务队列取任务。
    3.你的主线程要能保证不能创建重复任务。
    raysonx
        5
    raysonx  
       2016-09-16 16:53:51 +08:00 via iPad
    detach 线程通常只是为了让线程退出后资源会被自动回收。
    如果你不加节制地创建线程的话,问题依然不会得到解决。
    raysonx
        6
    raysonx  
       2016-09-16 17:00:07 +08:00 via iPad
    再一个题外话,如果程序跑在 Linux 上,还可以尝试用 dnotify 和 inotify 让内核主动告知文件系统变化,避免用循环手动扫描
    wangxiaoer
        7
    wangxiaoer  
       2016-09-16 18:44:55 +08:00
    你这完全是 XY problem( http://mywiki.wooledge.org/XyProblem) .

    @raysonx 已经提到了,合理的做法是子进程自己根据某些 flag 控制进程是否结束,并且有责任在退出前释放自己占用的资源
    Knights
        8
    Knights  
       2016-09-16 18:58:35 +08:00 via iPad
    如果主线程可以阻塞的话就在主线程里移动文件吧,不能阻塞的话试试异步。
    techmoe
        9
    techmoe  
       2016-09-16 19:01:46 +08:00 via Android
    4 楼正解,感觉这个逻辑设计的有缺陷
    可以考虑像一些下载器一样设置最大同时删除(下载)数这种功能
    davy1995
        10
    davy1995  
       2016-09-16 19:05:27 +08:00 via Android
    线程池?
    missdeer
        11
    missdeer  
       2016-09-16 19:23:08 +08:00
    4 楼正解
    子线程为什么不自己结束退出?
    频繁创建新的线程不如用线程池。
    longchisihai
        12
    longchisihai  
    OP
       2016-09-16 19:36:01 +08:00
    感谢大家的回复!
    reus
        13
    reus  
       2016-09-16 19:45:52 +08:00
    用 go ,监视文件夹、并行移动、限制并行数量都有了
    https://gist.github.com/reusee/cc61fbbcd9229a89ad01cbb6ed97987e
    alqaz
        14
    alqaz  
       2016-09-16 19:48:57 +08:00 via Android
    发信号
    wizardforcel
        15
    wizardforcel  
       2016-09-16 21:55:59 +08:00
    不如这样,创建固定数量的线程,并使用 threading 模块的 queue ,主线程扫描文件之后存进 queue 里面,子线程循环读取 queue ,如果没有内容就 sleep ,有内容就处理。
    8bit
        16
    8bit  
       2016-09-17 19:32:12 +08:00
    这不是生产者与消费者问题吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3385 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:51 · PVG 08:51 · LAX 16:51 · JFK 19:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.