如何在Python中将TCP服务器放到另一个线程上
我想用Python写一个守护进程,但我不知道怎么用线程来启动一个并行的TCP服务器。而且我也不确定应该用哪种类型的服务器:asyncore、SocketServer还是socket?
这是我代码的一部分:
import os
def demonized():
child_pid = os.fork()
if child_pid == 0:
child_pid = os.fork()
if child_pid == 0: #fork twice for demonize
file = open('###', "r") # open file
event = file.read()
while event:
#TODO check for changes put changes in list variable
event = file.read()
file.close()
else:
sys.exit(0)
else:
sys.exit(0)
if __name__ == "__main__":
demonized()
在一个循环中,我有一个列表变量,每次循环都会添加一些数据。我想在这个循环中启动一个线程,让TCP服务器等待连接。如果有客户端连接,就把这些数据发送给它(同时清空变量)。所以我不需要处理多个客户端,因为一次只会有一个客户端连接。实现这个的最佳方法是什么?
谢谢。
2 个回答
-1
你想在 while event:...
循环中往列表里添加东西,同时又想使用这个列表吗?如果是这样的话,你就有两个写入者,这样的话你需要想办法保护你的列表。
在这个例子中,使用了 SocketServer.TCPServer
和 threading.Lock
:
import threading
import SocketServer
import time
class DataHandler(SocketServer.StreamRequestHandler):
def handle(self):
self.server.list_block.acquire()
self.wfile.write(', '.join(self.server.data))
self.wfile.flush()
self.server.data = []
self.server.list_block.release()
if __name__ == '__main__':
data = []
list_block = threading.Lock()
server = SocketServer.TCPServer(('localhost', 0), DataHandler)
server.list_block = list_block
server.data = data
t = threading.Thread(target=server.serve_forever)
t.start()
while True:
list_block.acquire()
data.append(1)
list_block.release()
time.sleep(1)
8
如果你想避免重复写一些常规的代码,Python很快会有一个标准模块,可以处理fork()
和标准输入输出的操作(你还没把这些加到你的程序里吗?),这样就能让你的程序变成一个守护进程。你现在就可以从以下链接下载并使用这个模块:
http://pypi.python.org/pypi/python-daemon
在一个单独的线程中运行TCP服务器通常很简单:
import threading
def my_tcp_server():
sock = socket.socket(...)
sock.bind(...)
sock.listen()
while True:
conn, address = sock.accept()
...
... talk on the connection ...
...
conn.close()
def main():
...
threading.Thread(target=my_tcp_server).start()
...
我强烈建议你不要尝试让你的文件读取线程和处理socket的线程通过自己设计的列表和锁来进行交流;这样的方案很难实现,也很难维护。相反,建议使用标准库中的Queue.Queue()
类,它会为你正确处理所有的锁定和添加操作。