不断运行python脚本,通过终端调用函数

时间:2011-07-11 04:12:02

标签: python networking

我甚至不确定的快速问题是可能的:3

我有一个python脚本,一个连接到服务器并保持连接的网络脚本,直到我断开连接或它踢我(它通常不应该),这是不断接收数据和执行其他任务。

我很好奇脚本运行时是否一切都可以从脚本中触发函数?在脚本运行时说,如果我有向服务器发送某种数据的冲动,我可以输入它并将其发送到处理这个的函数吗?

不确定是否有可能,因为我从来没有尝试过甚至看过它。如果它有帮助,我在Ubuntu linux上从终端运行脚本。

5 个答案:

答案 0 :(得分:1)

解决此类问题的常用“UNIX方式”是套接字和标准输入文件描述符上的pollselect。然后,您可以在stdin文件描述符上的'IN'事件中的套接字和终端输入上的'IN'事件中处理网络输入。

这不能移植到Windows(这很糟糕),但这是在类UNIX系统上最自然的方式。并且你没有得到线程带来的所有问题(通常也需要在Python中进行轮询,否则它们会变得'不可杀死')。

答案 1 :(得分:1)

看看gevent

  

gevent是一个基于协程的Python网络库,它使用   greenlet提供了一个高级同步API   libevent事件循环。

gevent.socket

答案 2 :(得分:1)

Jacek Konieczny的解决方案很简单。如果您想要更灵活的消息传递,请考虑ZeroMQ。这为您提供了大量功能,可以轻松地围绕主程序创建各种消息传递解决方案。使用单个线程,您的主程序将如下所示:

#!/usr/bin/env python

import zmq
from time import sleep

CTX = zmq.Context()

incoming = CTX.socket(zmq.PULL)
incoming.bind("tcp://127.0.0.1:3000")

outgoing = CTX.socket(zmq.PUB)
outgoing.bind("tcp://127.0.0.1:3001")

# Poller for the incoming messages
poller = zmq.Poller()
poller.register(incoming, zmq.POLLIN)

def main():
    while True:
        # Do things on the network
        print("[Did things on the network]")
        # Send messages if you want
        outgoing.send("Important message")
        # Poll for incoming messages
        socks = dict(poller.poll(zmq.NOBLOCK))
        if incoming in socks and socks[incoming] == zmq.POLLIN:
            message = incoming.recv()
            # Handle message
            print("[Handled message '%s']" % message)

        sleep(1) # Only for this dummy program

if __name__ == "__main__":
    main()

然后,您将编写一个客户端(使用任何具有ZeroMQ绑定的语言),该客户端推送和订阅来自主程序的消息。示例推动器:

#!/usr/bin/env python

import zmq

CTX = zmq.Context()

pusher = CTX.socket(zmq.PUSH)
pusher.connect("tcp://127.0.0.1:3000")

def main():
    pusher.send("Message to main program")

if __name__ == "__main__":
    main()

订阅者示例:

#!/usr/bin/env python

import zmq

CTX = zmq.Context()

subscriber = CTX.socket(zmq.SUB)
subscriber.connect("tcp://127.0.0.1:3001")
subscriber.setsockopt(zmq.SUBSCRIBE, "")

def main():
    while True:
        msg = subscriber.recv()
        print("[Received message] %s" % msg)

if __name__ == "__main__":
    main()

听起来你想要将推送器和用户程序合二为一。如果您决定使用ZeroMQ,请查看the excellent user guide

您当然也可以将ZeroMQ用于多个线程或进程(只是注意不要在线程之间共享单个ZeroMQ套接字)。

答案 3 :(得分:0)

如果没有更多细节,我只能为您提供一般性的想法。为了一次做两件事(从服务器下载并等待数据发送),您将需要使用多个线程或进程。有一个包含多个线程here的示例的教程。如果您使用多个流程,则会使用multiprocessing包。

使用任一解决方案,您都需要类似的设置。我会在其余部分使用术语线程,但如果您使用多个进程,则可以轻松地将其替换为进程。你可能(至少)有一个线程来发送和接收数据(这可能是两个线程)和一个单独的线程来等待发送的东西。这是the producer/consumer problem的简化示例。等待命令/数据的线程将是生成要发送的数据的简单输入循环,而发送数据的线程在发送数据时消耗数据服务器。

答案 4 :(得分:0)

将您的服务器内容粘贴到另一个帖子中(调查threading模块)并使用主线程通过raw_input / input与用户进行互动。

相关问题