龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > python编程 >

探寻python多线程ctrl+c退出问题解决方案(2)

时间:2014-10-24 02:34来源:网络整理 作者:网络 点击:
分享到:
只能把线程设成daemon才能让主线程不等待,能够接受ctrl-c信号,但是又不能让子线程立即结束,那么只能采用传统的轮询方法了,采用sleep间歇省点cpu吧

只能把线程设成daemon才能让主线程不等待,能够接受ctrl-c信号,但是又不能让子线程立即结束,那么只能采用传统的轮询方法了,采用sleep间歇省点cpu吧:
 

复制代码 代码如下:

# -*- coding: utf-8 -*- 
import time,signal,traceback 
import sys 
import threading 
start=time.time() 
def foreverLoop(): 
    start=time.time() 
    while 1: 
        time.sleep(1) 
        print time.time() 
        if time.time()-start>5: 
            break 
             
thread_=threading.Thread(target=foreverLoop) 
thread_.setDaemon(True) 
thread_.start() 
 
#主线程wait住了,不能接受信号了 
#thread_.join() 
 
def _exitCheckfunc(): 
    print "ok" 
    try: 
        while 1: 
            alive=False 
            if thread_.isAlive(): 
                alive=True 
            if not alive: 
                break 
            time.sleep(1)   
    #为了使得统计时间能够运行,要捕捉  KeyboardInterrupt :ctrl-c       
    except KeyboardInterrupt, e: 
        traceback.print_exc() 
    print "consume time :",time.time()-start 
         
threading._shutdown=_exitCheckfunc 

   缺点:轮询总会浪费点cpu资源,以及battery.

有更好的解决方案敬请提出。

ps1: 进程监控解决方案 :

用另外一个进程来接受信号后杀掉执行任务进程,牛

复制代码 代码如下:

# -*- coding: utf-8 -*- 
import time,signal,traceback,os 
import sys 
import threading 
start=time.time() 
def foreverLoop(): 
    start=time.time() 
    while 1: 
        time.sleep(1) 
        print time.time() 
        if time.time()-start>5: 
            break 
 
class Watcher: 
    """this class solves two problems with multithreaded
    programs in Python, (1) a signal might be delivered
    to any thread (which is just a malfeature) and (2) if
    the thread that gets the signal is waiting, the signal
    is ignored (which is a bug).
 
    The watcher is a concurrent process (not thread) that
    waits for a signal and the process that contains the
    threads.  See Appendix A of The Little Book of Semaphores.
    http://greenteapress.com/semaphores/
 
    I have only tested this on Linux.  I would expect it to
    work on the Macintosh and not work on Windows.
    """ 
 
    def __init__(self): 
        """ Creates a child thread, which returns.  The parent
            thread waits for a KeyboardInterrupt and then kills
            the child thread.
        """ 
        self.child = os.fork() 
        if self.child == 0: 
            return 
        else: 
            self.watch() 
 
    def watch(self): 
        try: 
            os.wait() 
        except KeyboardInterrupt: 
            # I put the capital B in KeyBoardInterrupt so I can 
            # tell when the Watcher gets the SIGINT 
            print 'KeyBoardInterrupt' 
            self.kill() 
        sys.exit() 
 
    def kill(self): 
        try: 
            os.kill(self.child, signal.SIGKILL) 
        except OSError: pass 
 
Watcher()             
thread_=threading.Thread(target=foreverLoop) 
thread_.start() 

 注意 watch()一定要放在线程创建前,原因未知。。。。,否则立刻就结束

精彩图集

赞助商链接