没有STDOUT的两个python脚本之间的进程间通信
Posted
技术标签:
【中文标题】没有STDOUT的两个python脚本之间的进程间通信【英文标题】:Interprocess Communication between two python scripts without STDOUT 【发布时间】:2018-07-16 19:36:55 【问题描述】:我正在尝试创建一个监控所有线程的 Monitor 脚本或一个运行多个记录器、多个线程的大型 python 脚本。
我可以从 Monitor.py 运行子进程并转发可能包含我的线程状态的 STDOUT。但由于有几个记录器正在运行,我看到其他记录在其中..
问题:如何将主脚本作为一个单独的进程运行并获取自定义消息、线程状态而不干扰日志记录。 (将 PIPE 作为参数传递?)
Main_Script.py * 运行多个线程 * 每个线程都有单独的 Logger。
Monitor.py * 启动 Main_script.py * 监控 MainScript.py 中的每个线程(将来可能会从 Main_script 获取其他消息)
到目前为止,我尝试了子进程,来自 Multiprocessing 的进程。
子进程让我启动 Main_script 并将标准输出转发回监视器,但我看到通过同一个标准输出进入的线程日志记录。我正在使用“import logging”库将每个线程的数据记录到单独的文件中。
我尝试了 Multiprocessing 中的“process”。我不得不将 main_script.py 的主函数作为一个进程调用,并从 monitor.py 向它发送一个 PIPE 参数。现在,当我运行 top 命令时,我无法将 Main_script.py 视为一个单独的进程。
【问题讨论】:
问题:所有记录器都需要访问所有行还是负载平衡? 我认为记录器是根据关键字进行记录的……然后将它们拉入单独的文件中…… 【参考方案1】:通常,您希望将子进程更改为像典型的 Unix 用户空间工具一样工作:日志记录和其他边带信息进入标准错误(或文件,或系统日志等),只有实际输出转到标准输出。
那么,问题很简单:只需将stdout
捕获到您处理的PIPE
,然后将stderr
捕获到另一个PIPE
,或者将其传递给真正的stderr
。
如果由于某种原因这不合适,您需要为 IPC 提供一些其他机制:Unix 或 Windows 命名管道,通过在 fork
/exec
上泄漏文件描述符而传递的匿名管道,然后将 fd 作为参数传递、Unix 域套接字、TCP 或 UDP localhost 套接字、更高级别的协议(如 TCP 套接字之上的 Web 服务)、mmap
ped 文件、匿名 mmap
s 或您之间传递的管道通过 Unix 域套接字或 Windows API 调用处理,...
如您所见,有很多选择。除了您想要“自定义消息”之外,如果对您的问题一无所知,就不可能告诉您您想要哪一个。
虽然我们正在这样做:如果您可以围绕multiprocessing
而不是subprocess
重写您的代码,那么该模块中内置了很好的高级抽象。例如,您可以使用Queue
自动管理同步和阻塞,还可以管理酸洗/解酸,因此您可以只传递任何(可酸洗的)对象,而不必担心序列化为文本和解析文本。或者,您可以创建共享内存来保存 int32 对象数组、NumPy 数组或您使用ctypes
定义的任意结构。等等。当然,您可以自己构建相同的抽象,而无需使用 multiprocessing
,但是当它们开箱即用时会容易得多。
最后,虽然您的问题被标记为 ipc
和 pipe
,并且标题为“进程间通信”,但您的描述是指线程,而不是进程。如果你真的在一个进程中使用了一堆线程,你就不需要这些了。
您可以将结果粘贴在 queue.Queue
上,或者将它们存储在 list
或 deque
中,并在其周围加上 Lock
,或者传入一个回调以在每个新结果中调用,或者使用像concurrent.futures.ThreadPoolExecutor
这样的高级抽象,并返回Future
对象或Future
s的迭代器等。
【讨论】:
以上是关于没有STDOUT的两个python脚本之间的进程间通信的主要内容,如果未能解决你的问题,请参考以下文章
将 stdout 和 stderr 管道传输到 shell 脚本中的两个不同进程?
Python 3 TypeError: must be str, not bytes with sys.stdout.write()