快速的問題,我是從來沒有肯定是可能的:3不斷運行python腳本,通過終端調用函數
我有一個python腳本,連接到服務器,並保持連接直到我要麼斷開網絡腳本或者它踢我(它通常不應該),它不斷地接收數據和做其他任務。
我很好奇,腳本運行時是否有可能觸發腳本中的函數?在腳本運行的時候說,如果我有將數據發送到服務器的衝動,我可以輸入它並將它發送到處理該數據的函數?
不太確定是否有可能,因爲我從來沒有嘗試甚至沒有看到它完成。如果有幫助,我在Ubuntu Linux上運行終端上的腳本。
快速的問題,我是從來沒有肯定是可能的:3不斷運行python腳本,通過終端調用函數
我有一個python腳本,連接到服務器,並保持連接直到我要麼斷開網絡腳本或者它踢我(它通常不應該),它不斷地接收數據和做其他任務。
我很好奇,腳本運行時是否有可能觸發腳本中的函數?在腳本運行的時候說,如果我有將數據發送到服務器的衝動,我可以輸入它並將它發送到處理該數據的函數?
不太確定是否有可能,因爲我從來沒有嘗試甚至沒有看到它完成。如果有幫助,我在Ubuntu Linux上運行終端上的腳本。
沒有更多的細節,我只能爲您提供一般的想法。爲了一次執行兩件事(從服務器下載並等待數據發送),您將需要使用多個線程或進程。有一個教程,其中包含多個線程here的一些示例。如果您使用多個進程,則將使用multiprocessing程序包。
無論使用哪種解決方案,您都需要一個類似的設置。其餘部分我將使用術語線程,但如果使用多個進程,則可以輕鬆地將其替換爲進程。你可能會(至少)有一個線程來發送和接收數據(這可能是兩個線程)和一個單獨的線程來等待發送的東西。這是the producer/consumer problem的簡化示例。等待命令/數據的線程將是一個簡單的輸入循環,產生數據發送,而發送數據的線程將數據發送到服務器時會消耗。
將您的服務器內容粘貼到另一個線程中(調查threading
模塊),並使用主線程通過raw_input
/input
與用戶交互。
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套接字)。
如果需要,我可以共享代碼,但這聽起來正是我想要的。基本上,它幾乎是一個(授權的)機器人,它通過TCPConnection連接到服務器並穩定地接收和發送數據。我試圖做的是在一切正在運行的情況下,能夠調用其中一個函數,並在不中斷程序的情況下將數據發送到該函數。例如,機器人可能有一些硬編碼的數據來響應服務器發送的內容,但是如果我希望能夠發送一些自定義的內容(比如消息到遊戲聊天)。 – WeaponsTheyFear
您還可以使用單線程異步事件循環更簡單地執行這些類型的IO綁定多路複用。像Twisted框架可以使用,它可能已經支持這個內置的。 – Keith