监控多进程

Monitoring Multiprocess

我尝试制作一个请求用户输入的程序,并且 reader 函数打印输入,而输入函数不会阻塞 reader 函数。

这是我能做的

import multiprocessing as mp
import time


def ProInput(queue):
    while True:
        if queue.empty():
            print("{} waiting an item".format(mp.current_process().name))
        else:
            item = queue.get()
            if(item == 'exit'):
                break;
            else:
                print("{} processing {}".format(mp.current_process().name, item))
        time.sleep(1)



def InputRead(queue):
    while True:
        f = input("Insert your input :")
        queue.put(f)
        if(f == 'exit'):
            break;
        print("You insert {} into the system".format(f))

if __name__ == '__main__':
    st = time.time()
    q = mp.Queue()

    OutputSys = mp.Process(target=ProInput, name='Reader', args=(q,))
    OutputSys.daemon = True
    OutputSys.start()

    InputRead(q)

    et = time.time()
    OutputSys.join()
    print('Total running time {}'.format(et-st))

是否有任何方法可以在第一个终端中实现输入功能,在另一个终端中实现 Reader 功能?我的意思是,我可以在不受 Reader 函数干扰的情况下提供输入。My Program Looks like

常见问题解答

问:为什么不删除Reader中的打印功能?您的问题已解决!

答:我需要在我的程序中监控进程。

Ps。 : 随时纠正我的语法,因为我的英语还很烂。

请澄清你的意思,说 "the other terminal"。多处理本身不处理终端 (TTY/PTY) 分配或管理,并且一个进程具有多个用户可访问的终端有点不寻常。

如果我对你的问题的理解正确,你基本上希望你的程序受到监控(健康检查)。有两种常见的通用方法:

  • 如果您只需要在某处输出状态信息,请考虑写入某些日志(例如文件、系统日志或某些 UDP 套接字 - 考虑使用 logging 模块,因为它非常灵活) .然后设置您的监视解决方案将监视日志文件(或在套接字上侦听新消息)并做出相应的反应。

    即而不是 print 做这样的事情:

    import logging
    
    def setup_logger():
        # Just a very primitive example. Not a good code.
        logger = logging.getLogger("proinput")
        logger.setLevel(logging.DEBUG)
        # Or `fh = logging.StreamHandler(sys.stdout)`
        # to get the same effect as your previous print calls
        fh = logging.FileHandler("proinput.log")
        fh.setLevel(logging.DEBUG)
        formatter = logging.Formatter(
            "[%(asctime)s] %(process)d[%(processName)s] "
            "%(name)s (%(funcName)s): %(levelname)s: %(message)s"
        )
        fh.setFormatter(formatter)
        logger.addHandler(fh)
        return logger
    
    def pro_input(queue):
        logger = setup_logger()
        while True:
            ...
            logger.info("Waiting for an item")
            ...
            logger.info("Processing: %s", repr(item))
    

    上面的示例非常原始、不灵活且无法很好地扩展。查看 logging documentation (esp. the tutorials and the section on configuring logging - that's what I meant when I said that logging is flexible) and a question on using logging with multiprocessing 了解更多信息。

    如果您真的想要两个终端,这种方法也可以满足您的 "multiple terminals" 情况。只需使用预先创建的终端设备(例如打开一个新的控制台 window、运行 tty 并且它会输出类似 /dev/pts/9 的内容)作为输出文件并传递它通过命令行选项或作为环境变量启动程序时。

  • 另一种选择是实现一个特殊的服务器(例如 HTTP 或简单的 TCP),允许监控软件连接并查询状态。这个想法是在你的程序中有一个单独的进程,专门为外部世界提供状态信息。

    这对于像您这样的交互式软件来说并不常见,但对于服务器来说,这是一种非常流行的实现健康检查的方法。如果您的软件是 "headless" 并且用户输入仅用于原型设计,请考虑查看 Prometheus。它有一个很好的检测库,可以通过 HTTP 轻松测量和输出数据。

您选择哪种方法(被动观察还是主动查询)取决于您的监控解决方案和您的个人喜好。