Interruptible thread join in Python

前端 未结 5 1872
暗喜
暗喜 2020-12-07 22:49

Is there any way to wait for termination of a thread, but still intercept signals?

Consider the following C program:



        
5条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-07 23:29

    I know I'm a bit late to the party, but I came to this question hoping for a better answer than joining with a timeout, which I was already doing. In the end I cooked something up that may or may not be a horrible bastardisation of signals, but it involves using signal.pause() instead of Thread.join() and signalling the current process when the thread reaches the end of its execution:

    import signal, os, time, sys, threading, random
    
    threadcount = 200
    
    threadlock = threading.Lock()
    pid = os.getpid()
    sigchld_count = 0
    
    def handle_sigterm(signalnum, frame):
        print "SIGTERM"
    
    def handle_sigchld(signalnum, frame):
        global sigchld_count
        sigchld_count += 1
    
    def faux_join():
        global threadcount, threadlock
        threadlock.acquire()
        threadcount -= 1
        threadlock.release()
        os.kill(pid, signal.SIGCHLD)
    
    def thread_doer():
        time.sleep(2+(2*random.random()))
        faux_join()
    
    if __name__ == '__main__':
        signal.signal(signal.SIGCHLD, handle_sigchld)
        signal.signal(signal.SIGTERM, handle_sigterm)
    
        print pid
        for i in xrange(0, threadcount):
            t = threading.Thread(target=thread_doer)
            t.start()
    
        while 1:
            if threadcount == 0: break
            signal.pause()
            print "Signal unpaused, thread count %s" % threadcount
    
        print "All threads finished"
        print "SIGCHLD handler called %s times" % sigchld_count
    

    If you want to see the SIGTERMs in action, extend the length of the sleep time in thread_doer and issue a kill $pid command from another terminal, where $pid is the pid id printed at the start.

    I post this as much in the hope of helping others as being told that this is crazy or has a bug. I'm not sure if the lock on threadcount is still necessary - I put it in there early in my experimentation and thought I should leave it in there in case.

提交回复
热议问题