如何将tcp服务器放在python中的另一个线程上

时间:2011-11-05 12:52:42

标签: python multithreading tcpserver

我尝试在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 个答案:

答案 0 :(得分:5)

如果您想避免重复样板,Python很快就会有一个标准模块执行fork()对和标准I / O操作(您还没有添加到程序中?)一个守护进程。您现在可以从以下位置下载并使用此模块:

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()
    ...

我强烈建议反对尝试让你的文件阅读器线程和你的套接字应答线程与你自己设计的列表和锁定对话;这样的计划很难工作,很难继续工作。相反,请使用标准库的Queue.Queue()类,它会为您完成所有锁定和追加。

答案 1 :(得分:-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)