Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 监控功能完成情况并与客户交谈_Python_Twisted - Fatal编程技术网

Python 监控功能完成情况并与客户交谈

Python 监控功能完成情况并与客户交谈,python,twisted,Python,Twisted,我想我正在做一些异步编程,我不知道如何解决这个问题。我在一个新线程上运行了一个函数X,在主线程上运行了一个扭曲的tcp服务器。我想在函数X完成其工作时向客户端传递一条消息。代码如下所示: val = None def x(): global val #do something to val and send message to client that val is ready class Server(protocol.Protocol): def connecti

我想我正在做一些异步编程,我不知道如何解决这个问题。我在一个新线程上运行了一个
函数X
,在主线程上运行了一个扭曲的tcp服务器。我想在
函数X
完成其工作时向客户端传递一条消息。代码如下所示:

val = None

def x():
    global val
    #do something to val and send message to client that val is ready

class Server(protocol.Protocol):
    def connectionMade(self):
        self.transport.write(b'REDPY*')

    def dataReceived(self, data):
        print("Packet: ",data)


class EchoFactory(protocol.Factory):
    def buildProtocol(self, addr):
        print("new client")
        return Server()

threading.Thread(target=x).start()

endpoints.serverFromString(reactor, "tcp:1235").listen(EchoFactory())
reactor.run()

我已经研究了twisted和事件处理中的延迟,我不确定该使用什么。

您基本上是在这里进行多线程编程。在主线程中使用Twisted并不重要。您仍然需要一些线程安全通信原语。Twisted唯一可能发挥作用的方法是,它提供了一些工具,可以在不使用线程的情况下实现您的目标。无论你的问题还是你的例子都不清楚你的目标是什么,所以我不能在这个方向上提供任何指导(所以,下一次,在你的问题中考虑更具体和更详细,以便得到更好的答案)。 您可以使用
Queue
作为线程安全(-ish)的线程间通信机制

import threading
from Queue import Queue

def x(reactor, queue):
    while True:
        item = queue.get()
        # ... processing

threading.Thread(target=x).start()

# ...
reactor.run()
您还可以跳过长时间运行的线程,只使用Twisted的线程池进行短期操作

a_deferred = deferToThread(some_task, ...)
a_deferred.addCallback(deal_with_result_of_task)

将消息从一个任务传递到另一个任务,然后通过网络传递到客户端是一件棘手的事情。当涉及到线程时,您可能会感觉自己在暮色地带工作:)除了糟糕的笑话,下面是一个基于您的示例的简单片段:

from queue import Queue, Empty
import threading

from twisted.internet import endpoints, protocol, reactor, task


def x(shutdown_event, queue):
    while not shutdown_event.is_set():
        # do something to val and send message to client that val is ready
        queue.put(b'data')

    print('thread done')


class Server(protocol.Protocol):
    def connectionMade(self):
        # append client to list in factory
        self.factory.clients.append(self)
        self.transport.write(b'REDPY*')

    def connectionLost(self, reason):
        # remove client from list after disconnection
        self.factory.clients.remove(self)

    def dataReceived(self, data):
        print("Packet: ",data)


class EchoFactory(protocol.Factory):

    protocol = Server

    def __init__(self):
        self.clients = []


def pop_from_queue(queue, factory):
    try:
        data = queue.get(timeout=0.5)

        # process data after this point

        # loop through the clients and send them stuff
        for client in factory.clients:
            # NOTE: ensure the data sent is in bytes
            client.transport.write(data)
    except Empty:
        pass


def main():
    factory = EchoFactory()
    queue = Queue()
    event = threading.Event()

    # when the reactor stops, set Event so that threads know to stop
    reactor.addSystemEventTrigger('before', 'shutdown', event.set)
    # periodically check and pop from the queue
    periodic_task = task.LoopingCall(pop_from_queue, queue, factory)
    periodic_task.start(1)

    threading.Thread(target=x, args=(event, queue)).start()
    endpoints.serverFromString(reactor, "tcp:1235").listen(factory)


main()
reactor.run()
你必须从中得到的基本东西是:

  • 线程之间有一个共享的
    队列
    对象

  • 工厂
    对象包含一个
    客户机列表

  • 删除了
    buildFactory
    重载,只需在
    EchoFactory
    中设置
    protocol
    属性。在这种情况下,你不需要做任何花哨的事情,所以最好还是别管它。此外,默认情况下,Twisted将在协议中设置
    self.factory
    属性

  • 当客户端连接到它附加到
    factory.clients
    时,在
    connectionLost

  • 有一个
    LoopingCall
    任务将定期从队列中弹出


我还添加了一个额外的关机
事件
,它是在反应堆关机时设置的,可以正常地关闭线程。如果有什么不清楚的地方,请评论,我会更详细地解释。

我正在尝试构建一个神经网络服务器,其中函数X基本上会在脚本执行后立即将权重加载到网络,并启动服务器来处理请求。为了处理请求,服务器需要向客户端发送消息,表明神经网络已加载权重并准备就绪。谢谢!这就是我需要的。