Python 3超时的可选用户输入

时间:2016-03-14 00:27:29

标签: python-3.x input multiprocessing

我正在尝试创建一个要求用户输入的代码,如果在一定时间内未给出该输入,则将采用默认值并继续执行其余代码而无需用户输入。我在Windows 10上运行Python 3.5.1。

我已查看过:Keyboard input with timeout in PythonHow to set time limit on raw_inputTimeout on a function callPython 3 Timed Input黑色装箱答案,但没有一个答案适合,因为它们在Windows上无法使用(主要使用仅在linux上可用的signal.SIGALRM),或者要求用户按Enter键以退出输入。

基于上述答案,我尝试使用多处理来解决一个解决方案(我认为它应该工作)创建一个进程来请求输入并创建另一个进程以在超时期限之后终止第一个进程。

import multiprocessing
from time import time,sleep

def wait(secs):
    if secs == 0:
        return
    end = time()+secs
    current = time()
    while end>current:
        current = time()
        sleep(.1)
    return

def delay_terminate_process(process,delay):
    wait(delay)
    process.terminate()
    process.join()

def ask_input(prompt,term_queue,out_queue):
    command = input(prompt)
    process = term_queue.get()
    process.terminate()
    process.join()
    out_queue.put(command)

##### this doesn't even remotly work.....
def input_with_timeout(prompt,timeout=15.0):   
    print(prompt)
    astring = 'no input'
    out_queue = multiprocessing.Queue()
    term_queue = multiprocessing.Queue()
    worker1 = multiprocessing.Process(target=ask_input,args=(prompt,term_queue,out_queue))
    worker2 = multiprocessing.Process(target=delay_terminate_process,args=(worker1,timeout))
    worker1.daemon = True
    worker2.daemon = True
    term_queue.put(worker2)
    print('Through overhead')
    if __name__ == '__main__':
        print('I am in if statement')
        worker2.start()
        worker1.start()
        astring = out_queue.get()
    else:
        print('I have no clue what happened that would cause this to print....')
        return
    print('returning')

    return astring

please = input_with_timeout('Does this work?',timeout=10)

但这种情况很糟糕而且收益率很高:

    Does this work?
    Through overhead
    I am in if statement
    Traceback (most recent call last):
      File "C:\Anaconda3\lib\multiprocessing\queues.py", line 241, in _feed
        obj = ForkingPickler.dumps(obj)
      File "C:\Anaconda3\lib\multiprocessing\reduction.py", line 50, in dumps
        cls(buf, protocol).dump(obj)
      File "C:\Anaconda3\lib\multiprocessing\queues.py", line 58, in __getstate__
        context.assert_spawning(self)
      File "C:\Anaconda3\lib\multiprocessing\context.py", line 347, in assert_spawning
        ' through inheritance' % type(obj).__name__
    RuntimeError: Queue objects should only be shared between processes through inheritance
    Does this work?
    Through overhead
    I have no clue what happened that would cause this to print....
    Does this work?Process Process-1:
    Traceback (most recent call last):
      File "C:\Anaconda3\lib\multiprocessing\queues.py", line 241, in _feed
        obj = ForkingPickler.dumps(obj)
      File "C:\Anaconda3\lib\multiprocessing\reduction.py", line 50, in dumps
        cls(buf, protocol).dump(obj)
      File "C:\Anaconda3\lib\multiprocessing\process.py", line 287, in __reduce__
        'Pickling an AuthenticationString object is '
    TypeError: Pickling an AuthenticationString object is disallowed for security reasons
    Traceback (most recent call last):
      File "C:\Anaconda3\lib\multiprocessing\process.py", line 254, in _bootstrap
        self.run()
      File "C:\Anaconda3\lib\multiprocessing\process.py", line 93, in run
        self._target(*self._args, **self._kwargs)
      File "C:\Anaconda3\saved_programs\a_open_file4.py", line 20, in ask_input
        command = input(prompt)
    EOFError: EOF when reading a line
    Does this work?
    Through overhead
    I have no clue what happened that would cause this to print....
    Traceback (most recent call last):
      File "C:\Anaconda3\lib\multiprocessing\queues.py", line 241, in _feed
        obj = ForkingPickler.dumps(obj)
      File "C:\Anaconda3\lib\multiprocessing\reduction.py", line 50, in dumps
        cls(buf, protocol).dump(obj)
      File "C:\Anaconda3\lib\multiprocessing\queues.py", line 58, in __getstate__
        context.assert_spawning(self)
      File "C:\Anaconda3\lib\multiprocessing\context.py", line 347, in assert_spawning
        ' through inheritance' % type(obj).__name__
    RuntimeError: Queue objects should only be shared between processes through inheritance
    Process Process-2:
    Traceback (most recent call last):
      File "C:\Anaconda3\lib\multiprocessing\process.py", line 254, in _bootstrap
        self.run()
      File "C:\Anaconda3\lib\multiprocessing\process.py", line 93, in run
        self._target(*self._args, **self._kwargs)
      File "C:\Anaconda3\saved_programs\a_open_file4.py", line 16, in delay_terminate_process
        process.terminate()
      File "C:\Anaconda3\lib\multiprocessing\process.py", line 113, in terminate
        self._popen.terminate()
    AttributeError: 'NoneType' object has no attribute 'terminate'

我真的不太了解多处理模块,虽然我已经阅读了官方文档但我不确定为什么会出现这个错误,或者为什么它在这个过程中似乎已经完成了3次函数调用。任何关于如何解决错误或以更干净的方式实现可选用户输入的帮助都将受到noob程序员的青睐。谢谢!

0 个答案:

没有答案