python exit a blocking thread?

十年热恋 提交于 2021-02-19 06:51:09

问题


In my code I loop though raw_input() to see if the user has requested to quit. My app can quit before the user quits, but my problem is the app is still alive until I enter a key to return from the blocking function raw_input(). Can I do to force raw_input() to return by maybe sending it a fake input? Could I terminate the thread that it's on? (the only data it has is a single variable called wantQuit).


回答1:


You can use this time out function that wraps your function. Here's the recipe from: http://code.activestate.com/recipes/473878/

def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
    '''This function will spwan a thread and run the given function using the args, kwargs and 
    return the given default value if the timeout_duration is exceeded 
    ''' 
    import threading
    class InterruptableThread(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
            self.result = default
        def run(self):
            try:
                self.result = func(*args, **kwargs)
            except:
                self.result = default
    it = InterruptableThread()
    it.start()
    it.join(timeout_duration)
    if it.isAlive():
        return it.result
    else:
        return it.result



回答2:


Why don't you just mark the thread as daemonic?

From the docs:

A thread can be flagged as a “daemon thread”. The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set through the daemon attribute.




回答3:


You might use a non-blocking function to read user input.
This solution is windows-specific:

import msvcrt
import time

while True:
    # test if there are keypresses in the input buffer
    while msvcrt.kbhit(): 
        # read a character
        print msvcrt.getch()
    # no keypresses, sleep for a while...
    time.sleep(1)

To do something similar in Unix, which reads a line at a time, unlike the windows version reading char by char (thanks to Aaron Digulla for providing the link to the python user forum):

import sys
import select

i = 0
while i < 10:
    i = i + 1
    r,w,x = select.select([sys.stdin.fileno()],[],[],2)
    if len(r) != 0:
        print sys.stdin.readline()

See also: http://code.activestate.com/recipes/134892/




回答4:


There is a post on the Python mailing list which explains how to do this for Unix:

# this works on some platforms:

import signal, sys

def alarm_handler(*args):
    raise Exception("timeout")

def function_xyz(prompt, timeout):
    signal.signal(signal.SIGALRM, alarm_handler)
    signal.alarm(timeout)
    sys.stdout.write(prompt)
    sys.stdout.flush()
    try:
        text = sys.stdin.readline()
    except:
        text = ""
    signal.alarm(0)
    return text


来源:https://stackoverflow.com/questions/552996/python-exit-a-blocking-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!