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

如何在python中将tcp服务器放在另一个线程上,python,multithreading,tcpserver,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

我尝试用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服务器启动一个线程,在循环中等待连接,如果客户端连接,则发送该数据(使用归零变量)。所以我不需要处理多个客户机,客户机一次只有一个。实现这一点的最佳方式是什么


谢谢。

当事件:…循环并同时提供此列表时,是否要将项目附加到
中的列表中?如果是这样,那么你有两个作者,你必须以某种方式保护你的名单

在示例中使用了
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)

如果您想避免重复样板文件,Python很快就会有一个标准模块来执行
fork()
对和标准I/O操作(您还没有将其添加到程序中?),使其成为守护进程。您可以立即从以下站点下载并使用此模块:

在单独的线程中运行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()
类,它可以为您正确执行所有锁定和追加操作。

您可以使用Twisted(),它是为基于网络的事件处理而设计的。最近的一次演示对我帮助很大-我知道
Queue
,但是这次演讲让我想到了类似于
事件的想法,我在标准库文档中看到过它,但不知道该怎么做-是David Beazley的“Python并发简介”-尽管David进行了专业培训,他已经慷慨地为大家展示了很多幻灯片:首先,这个解决方案应该使用
队列
,而不是用原语构建一个。其次,我不清楚它是否运行—Python不支持对列表对象调用
write()
,是吗?我得到
TypeError:需要一个字符缓冲区对象
@Kirill Teplinskiy它看起来像我需要的,除了
时间。sleep(1)
我的文件的更改速度可能超过秒(在这种情况下,我可能会丢失一些信息)。是否有某种方法可以在通过外部事件(打开与客户端的连接)(不在循环内部)循环时暂停
?flag\semaphore?@Brandon Craig Rhodes我不确定,但在发送前将数据列表转换为字符串可能会有所帮助。但是我不能正确地检查它now@user1027564,是的,需要转换为字符串。我在发布之前没有运行此代码。无论如何,看看布兰登的答案,尤其是在
队列中。这似乎是线程之间交换信息所需要的。这对我来说也是新的:)。但是我仍然建议使用
SocketServer.TCPServer
,而不是手动使用套接字。这与线程的
队列
相同,但用于网络。@Brandon Craig Rhodes,感谢您注意
队列
。我现在要研究它,因为它真的很有用。