鱼C论坛

 找回密码
 立即注册
查看: 2767|回复: 11

[已解决]python 多进程中使用 input() 报错的问题

[复制链接]
发表于 2021-11-22 17:38:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
大家好~~我在用 multiprocessing 包创建子进程时,发现了如下现象我在子进程里调用了 input() 函数,结果就报了 EOFError 的错。具体如下:

这是我的代码:
import multiprocessing


def fun1():

    s = input('请输入:')
    print(s)


if __name__ == '__main__':
    proc1 = multiprocessing.Process(target=fun1)
    proc1.start()

这是错误信息:
C:\Users\yy\AppData\Local\Microsoft\WindowsApps\python3.9.exe F:/python_test/main.py
请输入:Process Process-1:
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\multiprocessing\process.py", line 315, in _bootstrap
    self.run()
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\multiprocessing\process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "F:\python_test\main.py", line 77, in fun1
    s = input('请输入:')
EOFError: EOF when reading a line

我的问题是:
        1. 造成这个问题的原因是?我感觉是 input() 函数有什么特别的东西。
        2. 如果我想在子进程 proc1 中执行类似 input() 的功能,应该调用什么函数呢?

感觉大家阅读~~
最佳答案
2021-11-24 13:07:16
本帖最后由 hrpzcf 于 2021-11-24 13:08 编辑

子进程要打开标准输入输出流才能输入输出
import sys
import os
import multiprocessing


def fun1(mainpid):
    if os.getpid() != mainpid:  # os.getpid()获取当前进程id,如果跟mainpid不相等则说明是新进程
        print("是子进程,打开标准输入输出流...")
        # 以下两句为子进程打开标准输入输出流
        sys.stdin = os.fdopen(0, "r")  # 打开标准输入流
        sys.stdout = os.fdopen(1, "w")  # 打开标准输出流
    s = input("请输入:")
    print(s)


if __name__ == "__main__":
    mainpid = os.getpid()  # 获取当前进程id
    proc1 = multiprocessing.Process(target=fun1, args=(mainpid,))

    # 不能像下面一行这样将子进程设置为守护进程,否则主进程结束后子进程也跟着结束,一样不能输入
    # 如果一定要用这句设置守护进程,那主进程应该等待子进程结束,即末尾加 proc1.join()
    # proc1.daemon = True

    proc1.start()
    # proc1.join()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-24 12:07:02 | 显示全部楼层
据说 准输入是被主进程占用,只有主进程控制,所以子进程无法使用。
只能用传参的方式给子进程输入数据。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-24 13:07:16 | 显示全部楼层    本楼为最佳答案   
本帖最后由 hrpzcf 于 2021-11-24 13:08 编辑

子进程要打开标准输入输出流才能输入输出
import sys
import os
import multiprocessing


def fun1(mainpid):
    if os.getpid() != mainpid:  # os.getpid()获取当前进程id,如果跟mainpid不相等则说明是新进程
        print("是子进程,打开标准输入输出流...")
        # 以下两句为子进程打开标准输入输出流
        sys.stdin = os.fdopen(0, "r")  # 打开标准输入流
        sys.stdout = os.fdopen(1, "w")  # 打开标准输出流
    s = input("请输入:")
    print(s)


if __name__ == "__main__":
    mainpid = os.getpid()  # 获取当前进程id
    proc1 = multiprocessing.Process(target=fun1, args=(mainpid,))

    # 不能像下面一行这样将子进程设置为守护进程,否则主进程结束后子进程也跟着结束,一样不能输入
    # 如果一定要用这句设置守护进程,那主进程应该等待子进程结束,即末尾加 proc1.join()
    # proc1.daemon = True

    proc1.start()
    # proc1.join()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2021-11-24 19:17:14 | 显示全部楼层
哦哦,那路或多~

是不是说,如果不打开标准输入输出流,程序就不知道目前的输入是要传给子进程还是主进程?所以为了避免模糊才要求这样做

谢谢谢谢,我明白了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-24 19:18:52 | 显示全部楼层
hrpzcf 发表于 2021-11-24 13:07
子进程要打开标准输入输出流才能输入输出

谢谢回答!我明白啦

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-24 19:19:54 | 显示全部楼层
suchocolate 发表于 2021-11-24 12:07
据说 准输入是被主进程占用,只有主进程控制,所以子进程无法使用。
只能用传参的方式给子进程输入数据。

是的~根据3楼,可以在子进程里手动打开标准输入输出,这样就可以在子进程里输入数据啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-24 19:27:21 | 显示全部楼层
本帖最后由 阳间祝福 于 2021-11-24 19:29 编辑
hrpzcf 发表于 2021-11-24 13:07
子进程要打开标准输入输出流才能输入输出


新的问题。。。

input('请输入') 的“请输入”这几个字是乱码

_______________________________________________

哦哦我会了,在打开标准输入输出的时候改 encoding= 参数为 'utf8'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-24 19:42:50 | 显示全部楼层
阳间祝福 发表于 2021-11-24 19:17
哦哦,那路或多~

是不是说,如果不打开标准输入输出流,程序就不知道目前的输入是要传给子进程还是主进 ...

不是避免模糊,每个进程都有自己的标准输入输出流,而子进程默认不打开标准输入输出,所以要手动打开
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-25 09:09:00 | 显示全部楼层
hrpzcf 发表于 2021-11-24 19:42
不是避免模糊,每个进程都有自己的标准输入输出流,而子进程默认不打开标准输入输出,所以要手动打开

这样啊,明白啦

谢谢谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-25 09:26:35 | 显示全部楼层
只能用传参的方式给子进程输入数据
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-25 16:24:26 | 显示全部楼层
lixiaoqiang2020 发表于 2021-11-25 09:26
只能用传参的方式给子进程输入数据

我尝试了一下 3 楼给出的方法,即在子进程里先打开输入输出流,然后就可以使用 input() 啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-26 11:26:46 | 显示全部楼层
阳间祝福 发表于 2021-11-25 16:24
我尝试了一下 3 楼给出的方法,即在子进程里先打开输入输出流,然后就可以使用 input() 啦

GOOD
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-12 18:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表