如果两个 multiprocessing 可以在终端上请求输入,有没有办法暂停其中一个直到给出答案?
If two multiprocessing can request input on the terminal, is there a way to pause one of them until the answer is given?
从下面的代码中可以看出,两个多处理一起运行,但是两者都有一个时刻可以在终端中请求一个input()
,有什么办法可以暂停另一个多处理直到得到答案在终端中给出?
文件Code_One
加速解释的古老而简单的例子:
from time import sleep
def main():
sleep(1)
print('run')
sleep(1)
print('run')
sleep(1)
input('Please, give the number:')
文件Code_Two
加速解释的古老而简单的例子:
from time import sleep
def main():
sleep(2)
input('Please, give the number:')
sleep(1)
print('run 2')
sleep(1)
print('run 2')
sleep(1)
print('run 2')
sleep(1)
print('run 2')
sleep(1)
print('run 2')
文件Main_Code
:
import Code_One
import Code_Two
import multiprocessing
from time import sleep
def main():
while True:
pression = multiprocessing.Process(target=Code_One.main)
xgoals = multiprocessing.Process(target=Code_Two.main)
pression.start()
xgoals.start()
pression.join()
xgoals.join()
print('Done')
sleep(5)
if __name__ == '__main__':
main()
遇到这种情况我该如何处理?
在这个例子中,因为它不会暂停另一个 multi,每当它要求输入时就会发生这个错误:
input('Please, give the number:')
EOFError: EOF when reading a line
当然,这是可能的。为此,您需要使用某种进程间通信 (IPC) 机制来允许两个进程进行协调。 time.sleep
虽然不是最佳选择,但有更有效的方法可以解决这个问题。
可能最有效的方法是使用 multiprocessing.Event
,像这样:
import multiprocessing
import sys
import os
def Code_One(event, fno):
proc_name = multiprocessing.current_process().name
print(f'running {proc_name}')
sys.stdin = os.fdopen(fno)
val = input('give proc 1 input: ')
print(f'proc 1 got input: {val}')
event.set()
def Code_Two(event, fno):
proc_name = multiprocessing.current_process().name
print(f'running {proc_name} and waiting...')
event.wait()
sys.stdin = os.fdopen(fno)
val = input('give proc 2 input: ')
print(f'proc 2 got input {val}')
if __name__ == '__main__':
event = multiprocessing.Event()
pression = multiprocessing.Process(name='code_one', target=Code_One, args=(event, sys.stdin.fileno()))
xgoals = multiprocessing.Process(name='code_two', target=Code_Two, args=(event, sys.stdin.fileno()))
xgoals.start()
pression.start()
xgoals.join()
pression.join()
这将创建 event
object 和两个子进程。事件 object 有一个内部标志,从 False
开始,然后可以通过调用 event.set()
的任何进程切换 True
。如果一个进程在标志为 False
时调用 event.wait()
,则该进程将阻塞,直到另一个进程调用 event.set()
.
event
在parent进程中创建,并作为参数传递给每个子进程。 Code_Two
开始并调用 event.wait()
,它会阻塞直到 event
中的内部标志设置为 True
。 Code_One
立即执行,然后调用 event.set()
,它将 event
的内部标志设置为 True
,并允许 Code_Two
继续。此时两个进程都已返回并调用 join
,程序结束。
这有点老套,因为它还将 stdin
文件编号从 parent 传递到 child 进程。这是必要的,因为当子进程被分叉时,那些文件描述符被关闭,所以对于 child 进程使用 input
读取 stdin
它首先需要打开正确的输入流(这就是sys.stdin = os.fdopen(fno)
正在做)。将 sys.stdin
作为另一个参数发送到 child 是行不通的,因为 Python 用于为分叉进程设置环境的机制(sys.stdin
是一个 IO 包装器 object 并且不可腌制)。
从下面的代码中可以看出,两个多处理一起运行,但是两者都有一个时刻可以在终端中请求一个input()
,有什么办法可以暂停另一个多处理直到得到答案在终端中给出?
文件Code_One
加速解释的古老而简单的例子:
from time import sleep
def main():
sleep(1)
print('run')
sleep(1)
print('run')
sleep(1)
input('Please, give the number:')
文件Code_Two
加速解释的古老而简单的例子:
from time import sleep
def main():
sleep(2)
input('Please, give the number:')
sleep(1)
print('run 2')
sleep(1)
print('run 2')
sleep(1)
print('run 2')
sleep(1)
print('run 2')
sleep(1)
print('run 2')
文件Main_Code
:
import Code_One
import Code_Two
import multiprocessing
from time import sleep
def main():
while True:
pression = multiprocessing.Process(target=Code_One.main)
xgoals = multiprocessing.Process(target=Code_Two.main)
pression.start()
xgoals.start()
pression.join()
xgoals.join()
print('Done')
sleep(5)
if __name__ == '__main__':
main()
遇到这种情况我该如何处理?
在这个例子中,因为它不会暂停另一个 multi,每当它要求输入时就会发生这个错误:
input('Please, give the number:')
EOFError: EOF when reading a line
当然,这是可能的。为此,您需要使用某种进程间通信 (IPC) 机制来允许两个进程进行协调。 time.sleep
虽然不是最佳选择,但有更有效的方法可以解决这个问题。
可能最有效的方法是使用 multiprocessing.Event
,像这样:
import multiprocessing
import sys
import os
def Code_One(event, fno):
proc_name = multiprocessing.current_process().name
print(f'running {proc_name}')
sys.stdin = os.fdopen(fno)
val = input('give proc 1 input: ')
print(f'proc 1 got input: {val}')
event.set()
def Code_Two(event, fno):
proc_name = multiprocessing.current_process().name
print(f'running {proc_name} and waiting...')
event.wait()
sys.stdin = os.fdopen(fno)
val = input('give proc 2 input: ')
print(f'proc 2 got input {val}')
if __name__ == '__main__':
event = multiprocessing.Event()
pression = multiprocessing.Process(name='code_one', target=Code_One, args=(event, sys.stdin.fileno()))
xgoals = multiprocessing.Process(name='code_two', target=Code_Two, args=(event, sys.stdin.fileno()))
xgoals.start()
pression.start()
xgoals.join()
pression.join()
这将创建 event
object 和两个子进程。事件 object 有一个内部标志,从 False
开始,然后可以通过调用 event.set()
的任何进程切换 True
。如果一个进程在标志为 False
时调用 event.wait()
,则该进程将阻塞,直到另一个进程调用 event.set()
.
event
在parent进程中创建,并作为参数传递给每个子进程。 Code_Two
开始并调用 event.wait()
,它会阻塞直到 event
中的内部标志设置为 True
。 Code_One
立即执行,然后调用 event.set()
,它将 event
的内部标志设置为 True
,并允许 Code_Two
继续。此时两个进程都已返回并调用 join
,程序结束。
这有点老套,因为它还将 stdin
文件编号从 parent 传递到 child 进程。这是必要的,因为当子进程被分叉时,那些文件描述符被关闭,所以对于 child 进程使用 input
读取 stdin
它首先需要打开正确的输入流(这就是sys.stdin = os.fdopen(fno)
正在做)。将 sys.stdin
作为另一个参数发送到 child 是行不通的,因为 Python 用于为分叉进程设置环境的机制(sys.stdin
是一个 IO 包装器 object 并且不可腌制)。