博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ctrl+c关闭多线程python程序
阅读量:7113 次
发布时间:2019-06-28

本文共 2106 字,大约阅读时间需要 7 分钟。

项目中经常需要用到多线程,如果一个python程序用了多线程,当子线程没有结束时,用ctrl+c是关闭不了主线程的,这时候就只能用kill命令杀掉,这样会很麻烦。

所以探讨了下怎么ctrl+C关闭多线程python程序,也在网上查了很多别人的做法,自己做了很多实验,尝试了很多种方法,总结得出一个能用的方法就是,把子线程setDeamon(True),通过isAlive方法实现join的功能。

代码:

#encoding=utf-8__author__ = 'kevinlu1010@qq.com'import threadingfrom time import sleepdef f():        sleep(100)p=threading.Thread(target=f)p.setDaemon(True)p.start()# p.join()while 1:    if not p.isAlive():        break    sleep(1)print 'done'

当子线程很多的时候,可以用这个函数

def threads_join(threads):    '''    令主线程阻塞,等待子线程执行完才继续,使用这个方法比使用join的好处是,可以ctrl+c kill掉进程    '''    for t in threads:        while 1:            if t.isAlive():                sleep(10)            else:                break

这种做法的坏处就是令主线程阻塞,直到子线程执行完这个功能的实现太麻烦了,原本用join来实现就好方便很多

 

下面是研究的过程中的尝试,但是全部都实现不了ctrl+C关闭的功能

原始的多线程程序

def f():    sleep(100)p=threading.Thread(target=f)p.start()p.join()print 'done'

这是最原始的一个多线程程序。

尝试一:设置线程为守护线程,即加入

p.setDaemon(True)

但是ctrl+c,程序没反应,跟没加是一样的

尝试二:使用信号,因为ctrl c的时候系统会向程序发送sigint信号,所以我们可以令程序捕获这个信号,并调用os的kill方法杀死自己

import signalimport osimport threadingfrom time import sleepdef f(a,b):    print 'kill me'    os.kill(os.getpid(),signal.SIGKILL)def tf():    sleep(20)signal.signal(signal.SIGINT,f)p=threading.Thread(target=tf)p.start()p.join()print 'done'

程序运行后,我立刻按ctrl c ,主线程会等子线程sleep20后,才会print 'kill me',证明主线程在等待子线程执行的时候,即join的时候,是捕获不了系统发来的信号的,要等子线程执行完毕,才能捕获。所以这个方法还是不行。

尝试三,用一个标志来让子线程自己结束自己的运行

is_exit=0def f(a,b):    global is_exit    is_exit=1    print 'kill me'    os.kill(os.getpid(),signal.SIGKILL)def tf():    while not is_exit:        sleep(20)signal.signal(signal.SIGINT,f)p=threading.Thread(target=tf)p.start()while 1:    sleep(10)print 'done'

这里加入一个标志is_exit用来标志子线程是否继续执行,然后加入信号,当捕获关闭信号时,把is_exit改为1,令到子线程自己结束,由于主线程在join的状态下是接受不了信号的,所以这里让主线程处于一直等待的状态。

这个做法是能做到ctrl c关闭子线程的,缺点就是子线程需要做完一个循环才能结束,同时主线程没有了join的功能,适用于主线程在给子线程发放任务后就不需要做任何操作的情形。

 

所以总的来说,ctrl c不能关闭多线程的程序的主要原因是使用了join方法,一旦用了join,主线程就会一直处于阻塞状态,不接受任何外界的联系。但是join方法在实际的业务中是经常需要用到的,我查了很久也没有查到可以替代join的,同时可以被ctrl c的方法。上面第一个程序用到的使用alive方法来实现join的功能的做法算是一个不太好,但又不能不使用它的解决方案了,希望后面能找到更好的实现join功能的方法。

转载于:https://www.cnblogs.com/Xjng/p/3946222.html

你可能感兴趣的文章
Python 的 heapq 模块源码分析
查看>>
Jitsi快捷安装
查看>>
区块链技术的基本特点
查看>>
阿里云容器服务DaemonSet实践
查看>>
一个游戏拨账系统的数据库结算设计
查看>>
Kafka Network层解析
查看>>
css加载会造成阻塞吗?
查看>>
由一个绝对定位引发overflow:auto滚动问题产生的关于包含块(containing block)的思考...
查看>>
CS-231N-斯坦福李飞飞机器视觉课(Cydiachen版笔记+感悟)
查看>>
推荐一个有趣的Chrome扩展程序-查看任意网站的开发技术栈
查看>>
聊聊storm TridentWindowManager的pendingTriggers
查看>>
React 解决fetch跨域请求时session失效
查看>>
翻译_只需20行代码创造JavaScript模板引擎(二)
查看>>
Blockchain和Tangle哪一个是未来?
查看>>
apicloud拉起小程序并传递参数
查看>>
虚拟机Centos6.8安装MYSQL5.7,本地Navicat连接
查看>>
简单聊聊DOM
查看>>
【JavaScript】JavaScript Array 对象(数组)
查看>>
github 上有趣又实用的前端项目(持续更新,欢迎补充)
查看>>
opencv python 直方图均衡化
查看>>