代码之家  ›  专栏  ›  技术社区  ›  Ipsquiggle

多个python脚本向单个中心脚本发送消息

  •  3
  • Ipsquiggle  · 技术社区  · 16 年前

    我有许多用python 2.6编写的脚本可以任意运行。我希望有一个中央脚本来收集输出并将其显示在一个日志中。

    理想情况下,它将满足这些要求:

    • 每个脚本都将其消息发送到同一个“接收器”进行显示。
    • 如果第一个脚本尝试发送消息时接收器没有运行,则会启动它。
    • 接收器也可以手动启动和结束。(尽管如果结束,如果另一个脚本试图发送消息,它将重新启动。)
    • 脚本可以以任何顺序运行,甚至可以同时运行。
    • 运行在 窗户 . 多平台是更好的,但至少它需要在Windows上工作。

    我遇到了一些提示:

    从这些碎片中,我想我可以把一些东西拼凑起来。只是想知道是否有一个明显的“正确”的方法来做这件事,或者我是否可以从任何人的错误中吸取教训。

    3 回复  |  直到 16 年前
        1
  •  5
  •   Dan Head    16 年前

    我会考虑使用 logging.handlers.SocketHandler 对于消息传递部分,听起来您已经考虑了日志类型的用例。

    标准库日志记录工具非常灵活,并且由配置驱动,因此您应该能够使它们适应您的需求。

    这无法处理问题的自动重新启动部分。对于Unix,您可能只需要使用pid文件和 os.kill(pid, 0) 以检查它是否在运行,但我不知道它们在Windows世界中的等价物是什么。

        2
  •  1
  •   Dan Menes    16 年前

    我构建了一个使用Windows命名管道的服务器,使用以下密钥代码:

        def run( self ):
            # This is the main server loop for the Win32 platform
            import win32pipe
            import win32file
            self.pipeHandle = win32pipe.CreateNamedPipe(
                '\\\\.\\pipe\\myapp_requests',
                win32pipe.PIPE_ACCESS_DUPLEX,
                win32pipe.PIPE_TYPE_BYTE |
                win32pipe.PIPE_READMODE_BYTE |
                win32pipe.PIPE_WAIT,
                1,
                4096,
                4096,
                10000,
                None)
            if self.pipeHandle == win32file.INVALID_HANDLE_VALUE:
                print 'Failed to create named pipe %s!' % self.pipeName
                print 'Exiting...'
                sys.exit(1)
            while True:
                # Open file connection
                win32pipe.ConnectNamedPipe( self.pipeHandle )
    
                # Run the main message loop until it exits, usually because
                # of a loss of communication on the pipe
                try:
                    self.messageLoop()
                except ServerKillSignal:
                    break
    
                # Return the pipes to their disconnected condition and try again
                try: win32pipe.DisconnectNamedPipe( self.pipeHandle )
                except: pass
            win32file.CloseHandle( self.pipeHandle )
            print "Exiting server"
    

    方法 messageLoop() 从管道读取数据,使用 win32file.ReadFile() ,直到抛出win32file.error。然后它退出,允许run()重新启动它。

    在我的实现中,用户不太可能具有管理员访问权限,因此无法作为系统服务启动。相反,我对客户机进行了编码,以检查在'.\pipe\pyccf\u requests'处是否存在管道。如果它不存在,那么客户机将启动一个新的服务器进程。

        3
  •  0
  •   johntellsall    16 年前

    丹·海德的回答正是你想要的。

    项目2,“如果第一个脚本试图发送消息时接收器没有运行,则它已启动”,可能无法工作。必须运行某些程序才能接收消息。我建议编写一个启动时启动的恶魔进程,并告诉Windows在它死后重新启动它。