将相同的连续更新发送到由另一个线程

时间:2017-12-17 14:32:37

标签: python multithreading

我努力想要解决这个问题,所以希望得到一点意见。

我计划让一个运行套接字服务器的线程每隔一秒检查一次新的客户端连接。如果找到一个,它将为该连接生成一个线程,并在客户端断开连接后关闭它。这就是我的工作。

我想从主程序中获取传递给结束线程的信息,以便每个客户端都能收到相同的信息。我无法真正使用multiprocessing.Queue因为在第一个线程使用它之后会删除该项目(我无法在服务器线程中拦截它,因为更新将限制为每秒1次,并且主线程不知道有多少连接,所以有人有任何建议吗?

线程的布局有点像这样:

Main script (running many times per second)
    -server (running 1 time per second)
        -client (sending information as soon as it receives it, ideally in sync with the main script)
        -client
        -client

我想我可能会从服务器生成一个线程来接收输入,然后该线程将产生客户端线程并向每个线程发送一个不同的Queue项,但听起来应该少一个凌乱的方式。

编辑:中间线程的想法不起作用,不幸的是你不能跨线程传递连接或队列。

1 个答案:

答案 0 :(得分:0)

After multiple attempts I finally figured out a way that would work. As connections can't be passed across threads, the socket.accept needs to be done from within the client thread. To avoid spawning more than one, the loop is paused until the thread sends back word that it has a connection.

In order to send the same queue item to each of them, another thread is run that has access to all the queues, so it can take one item and duplicate it. As the list of queues changes all the time, it must be recreated after each connection.

Instead of copying over 100 lines of code, here is the general idea in pseudocode:

sock = socket.connect()

threads = []
queues = []
while True:

    #Start a client thread ready for connection
    #Make sure to empty the queue before receiving messages
    queues.append(Queue())
    threads.append(Thread(client_thread, (sock, queues[-1], main_queue)))
    threads[-1].start()

    #Start the middleman thread
    #It receives an input from one queue and sends it a list of other queues
    #Restart required when the number of threads changes
    middleman.quit()
    middleman = Thread(middleman_thread, (main_queue, queues))
    middleman.start()

    #Wait for connection to be made
    addr = queue.get()
    print '{}:{} connected.'.format(*addr)

    #Close any threads with disconnected clients
    for thread in threads:
        if not thread.isAlive():
             del thread
             del queue