2

我正在尝试编写一个 UDP 侦听器,该侦听器执行 API 调用作为响应,但基于接收到的 UDP 数据报中包含的数据。看来 callMultipleInThreads 在单个线程中运行这两个函数。收到 UDP 数据报后,我希望 functionOne 会在 functionTwo 在新线程中启动时结束(执行 API 调用),但事实并非如此。

import time
from twisted.internet import reactor, threads

def functionOne(x):
    print x

def functionTwo(x):
    time.sleep(10)
    print x

commands = [(functionOne, ["First Function"], {})]
commands.append((functionTwo, ["Second Function"], {}))
reactor.listenUDP(9999, threads.callMultipleInThread(commands))
reactor.run()

我是编写线程代码的新手。如何更好地允许第二个功能不阻止 functionOne 关闭?在 funtionTwo 中分叉 API 调用会是更好的方法吗?

4

1 回答 1

1

正如文档所解释的那样,threads.callMultipleInThread将在一个线程上运行您的函数,因此它们仍然可以相互阻塞。如果我理解您的目标,您应该将 functionTwo 推迟到它自己的新线程,而不是与 functionOne 共享同一个线程。有一个关于如何将阻塞调用与 Twisted 集成的快速部分,这是在阻塞调用上使用 deferToThread。

我注意到的最后一件事是协议实现。因此,我将展示一个简短的片段来演示如何在侦听 UDP 的同时在新线程上运行 functionTwo:

import time                                                                                                                                                                                                  
from twisted.internet import reactor, threads                                                                                                                                                                
from twisted.internet.protocol import DatagramProtocol                                                                                                                                                       


class DoNotBlockMeProtocol(DatagramProtocol):                                                                                                                                                                
    def datagramReceived(self, data, (host, port)):                                                                                                                                                          
        reactor.callLater(0, functionOne, "First Function")                                                                                                                                                  
        threads.deferToThread(functionTwo, "Second Function")                                                                                                                                                
        print "received %r from %s:%d" % (data, host, port)                                                                                                                                                          self.transport.write(data, (host, port))                                                                                                                                                             


def functionOne(x):                                                                                                                                                                                          
    print x                                                                                                                                                                                                  


def functionTwo(x):                                                                                                                                                                                          
    time.sleep(10)                                                                                                                                                                                           
    print x                                                                                                                                                                                                  

reactor.listenUDP(9999, DoNotBlockMeProtocol())                                                                                                                                                              
reactor.run()

为了看到它工作,在 linux shell 上运行它:

$ echo -n “foo” | nc -4u -w1 localhost 9999

您还可以在本指南中了解有关使用 UDP 的更多信息:https ://twistedmatrix.com/documents/current/core/howto/udp.html

于 2016-01-29T13:47:44.473 回答