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

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

代码:

#encoding=utf-8
__author__ = 'kevinlu1010@qq.com'
import threading
from time import sleep
def 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 signal
import os
import threading
from time import sleep
def 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=0
def 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功能的方法。

ctrl+c关闭多线程python程序的更多相关文章

  1. sublime text3点击ctrl+B无法运行Python程序?

    1.打开sublime text 3 ,选择 tools-->Build System-->New Build System.... 2.将下面代码块复制进新文件中,并命名为Python. ...

  2. 使用Notepad++编译运行C/C++/Python程序

    对我来说,比较常用的是C/C++/Python. 使用Notepad++编译运行单个源文件的C/C++/Python,比使用复杂的IDE更加快捷. 想要让Notepad++能够做到编译运行C/C++/ ...

  3. Notepad++编写运行python程序

    Notepad++编写运行python程序. 1.菜单栏->语言->P->Python设置语言为Python 2.写好代码后ctrl+s保存文件为py文件 3.菜单栏->运行, ...

  4. 第一阶段——CentOS6_Python3.6.1笔记(尚学堂-Python基础快速入门)+ 【补充】麦子-Python程序入门与进阶

    虚拟机环境: 设置网络 .修改网络地址 .设置网卡为nat模式 .确保物理机启动dhcp.net服务 .编辑文件:vim /etc/sysconfig/network-scripts/ifcfg-et ...

  5. 如何优雅地退出python程序

    如何优雅地退出python程序 一个单模的python程序,启动之后要能够优雅地关闭.即当用户按Ctrl+C或者kill pid的时候,程序都能从容关闭.实现起来非常简单. is_running = ...

  6. 如何在交互式环境中执行Python程序

    相信接触过Python的小伙伴们都知道运行Python脚本程序的方式有多种,目前主要的方式有:交互式环境运行.命令行窗口运行.开发工具上运行等,其中在不同的操作平台上还互不相同.今天,小编讲些Pyth ...

  7. [.net 面向对象程序设计进阶] (17) 多线程(Multithreading)(二) 利用多线程提高程序性能(中)

    [.net 面向对象程序设计进阶] (17) 多线程(Multithreading)(二) 利用多线程提高程序性能(中) 本节要点: 上节介绍了多线程的基本使用方法和基本应用示例,本节深入介绍.NET ...

  8. [.net 面向对象程序设计进阶] (16) 多线程(Multithreading)(一) 利用多线程提高程序性能(上)

    [.net 面向对象程序设计进阶] (16) 多线程(Multithreading)(一) 利用多线程提高程序性能(上) 本节导读: 随着硬件和网络的高速发展,为多线程(Multithreading) ...

  9. Python程序的常见错误(收集篇)

    关于Python Python是一门解释性的,面向对象的,并具有动态语义的高级编程语言.它高级的内置数据结构,结合其动态类型和动态绑定的特性,使得它在快速应用程序开发(Rapid Applicatio ...

随机推荐

  1. [JavaScript]转--如何让JS代码高大上

    原文出处:http://www.cnblogs.com/wenber/p/3630373.html 1,创造简短的写法 你可以这么写: 1 var slice = Array.prototype.sl ...

  2. (收藏)sokcet编程

    C# Socket网络编程精华篇 C#编写高性能网络服务器(源码) .net自动更新组件Ant 客户端服务器通信demo(附源码) 有了WCF,Socket是否已人老珠黄? Socket服务器整体架构 ...

  3. [转载]删除所有的.svn文件夹

    Windows 下,在DOS窗口中运行如下命令 dos 代码 for /r <你项目的路径> %i in (.svn) do rd /s /q %i Linux 下,可以先运行 显示出当前 ...

  4. IE, FF, Safari前端开发常用调试工具

    一些前端开发 IE 中的常用调试工具: Microsoft Script Debugger —— Companion.JS need to install this Companion.JS —— J ...

  5. TortoiseGit记住用户名和密码

    1.将项目从服务器Clone下来 2.然后在Repository上右键,打开设置 3.选择凭证 4.为当前Repository创建一个凭证,然后确定退出即可 5.然后再pull下,会直接提示你输入密码 ...

  6. spark下测试akka的分布式通讯功能

    采用的spark版本为1.1.0 scala版本为2.10.4 编写scala类文件myactors.scala: package bluejoe import akka.actor._ import ...

  7. Extjs搜索域使用

    要在使用的panel在预先加载搜索域类requires : ["Ext.ux.form.SearchField"],

  8. ios code style

    注释 建议使用VVDocumenter插件 多行注释 格式: /** 注释内容 */ 单行注释 格式: ///在对文件.类.函数进行注释时推荐使用多行注释,在函数体内对代码块进行注释时,使用单行注释 ...

  9. js调用本地 exe

      js方法 function Run(strPath) //only for ie { try { var objShell = new ActiveXObject("wscript.sh ...

  10. (二)JAVA使用POI操作excel

    1,创建一个时间格式的单元格 Demo4.java package com.wishwzp.poi; import java.io.FileOutputStream; import java.util ...