Python,显示终端不同部分中多个进程的输出

Python,显示终端不同部分中多个进程的输出,python,python-multiprocessing,python-curses,Python,Python Multiprocessing,Python Curses,我正在用Python运行一个多处理系统,我计划将终端窗口划分为4个象限,并在其中一个象限中显示每个进程的输出 因此,最终输出应该如下所示: ---------------------------------- | | | | PROCESS_01 | PROCESS_02 | | | | ---------------------------------- |

我正在用Python运行一个多处理系统,我计划将终端窗口划分为4个象限,并在其中一个象限中显示每个进程的输出

因此,最终输出应该如下所示:

----------------------------------
|                |                |
|   PROCESS_01   |   PROCESS_02   |
|                |                |
----------------------------------
|                |                |
|   PROCESS_03   |   PROCESS_04   |
|                |                |
----------------------------------

我有一个主文件,从这里开始单个进程:

如果名称=“\uuuuu main\uuuuuuuu”:
设置启动方法(“生成”)
p01=mp.Process(target=p01\u初始值设定项,args=(…)
p01.daemon=True
p01.开始()
p02=mp.Process(target=p02\u初始值设定项,args=(…)
p02.0=真
p02.开始()
p03=mp.Process(target=p03\u初始值设定项,args=(…)
p03.0=真
p03.开始()
p04=mp.Process(target=p04\u初始值设定项,args=(…)
p04.0=真
p04.开始()
我计划使用curses模块来实现这种可视化。
基本上在每个过程中,我都创建了一个不同的窗口。两者都具有相同的高度/宽度(rows_mid,cols_mid),但其思想是进程01的窗口应起源于(0,0),而进程02的窗口应起源于坐标(0,cols_mid),如下所示:

程序(01)


诅咒。initscr()
cols_tot=诅咒
rows\u tot=诅咒
x_mid=int(0.5*cols_tot)
y_mid=int(0.5*rows_tot)
self.win=诅咒.newwin(y_mid,x_mid,0,0)
self.win.addstr(0,0,***进程01***”)
自我胜利。addstr(随便什么)
程序02


诅咒。initscr()
cols_tot=诅咒
rows\u tot=诅咒
x_mid=int(0.5*cols_tot)
y_mid=int(0.5*rows_tot)
self.win=诅咒.newwin(y_mid,x_mid,0,x_mid)
self.win.addstr(0,0,***进程02***”)
自我胜利。addstr(随便什么)
但它并没有真正起作用。在开始时,只有进程_02的输出显示在正确的位置。 然后,只有进程_01出现,但是一些内容在进程_02的输出应该在的空间中可视化,如下所示


我能修一下吗?有没有比使用诅咒更好/更容易的替代方法?

如评论中所述:

  • 通过将输出写入日志文件并使用tmux,我可以以更简单的方式获得相同的结果

  • 如果想坚持“手动”方法,问题似乎是各个进程相互干扰,因此屏幕会被每个进程覆盖

  • 我通过在一个数组中收集每个进程的所有输出来解决这个问题,然后通过队列将输出发送回主进程并在那里打印

    程序(01)

    
    输出消息\u 01=[]
    输出消息\u 01.append('P01'的第一个输出)
    输出消息\u 01.append('P01'的第二次输出)
    ....
    ##限制数组中的消息总数(如果太多,则在终端中打印时超出窗口行限制)
    如果len(输出消息)>15:
    输出消息\u 01=输出消息\u 01[-15:]
    输出队列p01.put((输出消息01))
    
    程序02

    
    输出消息\u 02=[]
    输出消息\u 02.append('P02'的第一个输出)
    输出消息\u 02.append('P02'的第二次输出)
    ....
    如果len(输出消息)>15:
    输出消息\u 02=输出消息\u 02[-15:]
    输出队列p02.put((输出消息02))
    
    在主要过程中,我收集并打印所有内容

    主要过程

    创建面板 win11=curses.newwin(行中,列中,0,0) win12=curses.newwin(行中、列中、0、列中) win21=curses.newwin(行中,列中,行中,0) win22=curses.newwin(rows\u mid,cols\u mid,rows\u mid,cols\u mid) win11.addstr(0,0,“***进程01***”,curses.A_粗体) win12.addstr(0,0,“***进程02***”,curses.A_粗体) win21.addstr(0,0,“***进程03***”,curses.A_粗体) win22.addstr(0,0,“***进程04***”,curses.A_粗体) ##从process01获取带有输出消息的数组 p01\u messages=output\u queue\u p01.get() 对于行,枚举中的消息(p01_消息): win11.addstr(行,0,消息) win11.clrtool() ##从process02获取带有输出消息的数组 p02\u messages=output\u queue\u p02.get() 对于行,枚举中的消息(p02_消息): win12.addstr(行,0,消息) win12.clrtool() ##对于过程03和04也是如此。。。 win11.refresh() win12.refresh() win21.refresh() win22.refresh()
    同样,对于其他进程

    可能进程应该向主进程发送信息(使用队列),并且只有主进程应该更新屏幕。我怀疑当你运行很多咒语时,他们会试图控制屏幕上的所有文本,并删除其他咒语添加的文本。这实际上是我第一次尝试,但我尝试这样做,因为它看起来更…有序。无论如何,我回到了原始版本,我使用队列将输出发送回所有进程到主函数,并从那里打印所有内容。非常感谢。您正在重新发明
    tmux
    。只需让您的进程编写单独的日志,并在
    tmux
    中的单独窗格中对每个日志文件运行
    tail-f
    。我知道这很蹩脚,但我真的不知道tmux。非常感谢,它实际上比我自己手工做任何事情都容易(而且效果更好)。