如何同时独立运行 zmq 和其他 while True: ? [英] How to run a zmq and other while True: at the same time independently?

查看:73
本文介绍了如何同时独立运行 zmq 和其他 while True: ?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的服务器有这个代码:

I have this code for my server:

import time
import zmq

context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:5000")

while True:
    message = socket.recv()
    socket.send(b"World")
    print "sent"

while True:
    print "done."

我有一个单独的客户端脚本,每当我发送消息时,它都会通过 zmq 向这个脚本发送消息.在服务器上(此代码),如果我只有第一个 while True:,它会在我每次发送消息时打印sent",如果我只有第二个 while True:,它会打印done".不断.但是,如果我同时输入两者,它永远不会打印完成(或者如果我切换他们的顺序并同时输入两者,它在我发送消息时永远不会打印已发送").

I have a separate client script that sends a message through zmq to this one whenever i send a message. On the server (this code), if i only have the first while True:, it prints "sent" every time i send a message, and if i only have the second while True:, it prints "done." continuously. But if i put both, it never prints done (or if i switch their order and put both it never prints "sent" when i send a message").

作为输出,我希望它连续打印完成",并在收到消息时打印已发送".所以是这样的:

As an output i want it to continuously print "done.", and also print "sent" when I get a message. So something like this:

done.
done.
done.
done.
done.
sent
done.
lots more done....

基本上,我希望两个循环能够连续且完全独立地运行.

Basically i want both loops to run continuously and completely independently of each other.

注意我曾尝试使用多处理(例如在此处的第三个答案 How do I同时运行两个 python 循环?),但也无法让它工作.我试过如下:

N.B. I have tried using multiprocessing (such as in the 3rd answer here How do I run two python loops concurrently?), but couldn't get that to work either. I tried it as below:

import time
import zmq
from multiprocessing import Process

context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:5000")
i = time.time()

def zmq_loop():
    while True:
        message = socket.recv()
        socket.send(b"World")
        print "sent"

def done_loop():
    global i
    while True:
        i2 = time.time()-i
        if i2%2 == 0:
            print "done."

if __name__ == "__main__":
    Process(target=zmq_loop).start()
    Process(target=done_loop).start()

推荐答案

正如昨天在 this 中所解释的[CONCURRENT] 处理在技术上可以在 python 中以几种不同的方式实现,每种方式都有不同的成本.

As was explained yesterday in this, the [CONCURRENT]-processing is technically achievable in several different ways in python, each with a way different cost.

今天,让我们看看另一种方法 - 使用一个框架,该框架的开发动机完全相同 - 具有自然的 [CONCURRENT]-scheduling-already-in-DNA - 最初是为了轻松组合和流畅操作复杂的 GUI 人机交互 (MMI).

Today, let's have a look onto another approach - using a framework, that was developed with the very same motivation - having the natural [CONCURRENT]-scheduling-already-in-DNA - originally intended for easy composing and smooth operating complex GUI Man-Machine-Interactions ( MMI ).

这个框架可能并且会帮助你取得很多成就,因为它已经发展到非常关注完全相同的场景,在这些场景中必须同时监控不止一件事情:

This framework may and will help you achieve a lot, right due to the fact, it has evolved with a lot of care for exactly the same scenarios, where more than one thing has to be monitored at once:

欢迎使用 Tkinter GUI 框架,我们将仅将其用于智能并发操作事件处理程序.

Welcome to Tkinter GUI framework, which we will use just for its smart concurrently operated event handlers.

我多次感到惊讶,构建一个相当复杂的有限状态自动机 (FSA) 组合是多么容易,这些组合可以顺利地协作(FSA-s 的联盟),使用工具既可以独立,也可以隔离操作(每个 FSA 的内部逻辑),但能够轻松地将信号/消息从一个 FSA 传播到另一个(多个).是的,他们实际上可以在1-event-source-FSA:N-consumer(s)-FSA(s)

I was many times positively surprised, how easy it comes to build a quite complex composition of Finite-State-Automata ( FSA ), that smoothly cooperate together ( a coalition of FSA-s ), using tools for both independent, isolated operations ( the inner-logic of each FSA ), yet being easily able to propagate signals / messages from one FSA towards another(s). Yes, they can actually operate in 1-event-source-FSA : N-consumer(s)-FSA(s)

在那里您可以创建(使用 ZeroMQ 始终以非阻塞方式)处理程序 -- 一个 嗅探器" 用于定期检查(最好通过超时控制.poll() 方法到 { NACK | POSACK } 任何要阅读的东西 ) -- 另一个 reader"从 ZeroMQ Socket() 实例中实际读取(由来自嗅探器"的 POSACK 信号触发,如前所述——另一个 do-a-work-er" 用于人们可能希望操作的任何其他任务

There you can create ( with ZeroMQ always in a non-blocking manner ) handlers -- one "sniffer" for a regular checking ( best by a timeout-controlled .poll() method to { NACK | POSACK } anything to read ) -- another "reader" for actual reading from the ZeroMQ Socket() instance ( triggered by the POSACK-signal from the "sniffer", as was mentioned previously -- another "do-a-work-er" for any other task one may wish to operate

Tkinter .mainloop() 方法是全局控制器,它为你编排脏作业.

Tkinter .mainloop() method is the global controller, which orchestrates the dirty job for you.

Tkinter 中介的代理协同处理的高级概念始于 main(),简单如下:

The hich level concept of Tkinter-mediated agent's co-processing starts in main() as simple as:

def main():
    root = Tk()                      # INIT a Tk() instance
    root.lift()                      #      + make it visible
    app = myApplication( root )      # SET ( [HERE] are all your app gems )
    root.mainloop()                  # START the core event-handling orchestrator

Tkinter 可能看起来像一个装满各种 GUI 小工具的车库,它们与您的问题无关,但不要惊慌.

Tkinter might look as a garrage full of various GUI-gadgets, that have nothing to do with your problem, but don't panic.

Tkinter 拥有非常出色的工具,可以满足您的需求.

Tkinter has incredibly well created tools right for your needs.

  • 使用 <强>控制变量 将用作在其他独立和明确未协调的参与者之间存储、发出信号和传播值变化的手段(参考嗅探器"、阅读器"、工人"" 和任何其他... )

  • using control variables that will be used as a means for storing, signalling and propagating changes of values among otherwise independent and explicitly un-coordinated actors ( ref. "sniffer", "reader", "worker" and any others ... )

处理事件 - 真实的、抽象的甚至虚拟的

tools for handling events - real, abstract and even virtual

用于处理定时操作的工具 - 以几乎轻量级的实时系统的形式,使用具有接下来发生的首选时间的设置,.mainloop()-但要牢记
明确指定的时间 .after( thisAmountOfMILLISECONDS, callThisFUNCTION ) 或自由的 .after_idle( callAlwaysThatFUNCTION ).

tools for handling timed-operations - in a form of an almost a lightweight real-time system, using setups with preferred timing of what shall happen next, the .mainloop()-yet tasked to bear in mind
an explicitly specified timing .after( thisAmountOfMILLISECONDS, callThisFUNCTION ) or a liberal .after_idle( callAlwaysThatFUNCTION ).

使用这些已经很完美的工具,您确实不需要更多的东西来解决您的任务.

One does not need indeed anything more to go and solve your task, using these already perfect tools.

所以剩下的只是原则上你的创造力如何重用这些智能工具.

So all the rest is just in principle under your creativity how to re-use these smart tools.

让我们设置一个案例,当一个人想要同时处理(这里通过打印演示)几个独立的进程时.

Let's setup the case, when one wants to process ( here demonstrated by a printing ) several independent processes, all at the same time.

    >>> #-----------------------------------------------FAST MOCK-UP EXAMPLE
    >>> import Tkinter as tk                          # python27
    >>> root = tk.Tk()
    >>> root.protocol( "WM_DELETE_WINDOW", root.quit() )
    '3071841620Ldestroy'
    >>> #------VAR-------------------------------------IMPORTANT TOOL:
    >>> aStringVAR = tk.StringVar()
    >>> aStringVAR.set( "_init_" )

    >>> def aKeyPressEventHANDLER( anEvent ): # SIMPLE EventHANDLER,
            #                                 #        also ignites remote responsive processes
    ...     aTemplate = "[KEY]::{3: >10s}\n<s/n>::{0: >10d}\n(=@=)::{1: > 10d}\n^from::({5:})"
    ...     sString   = aTemplate.format( anEvent.serial,
    ...                                   anEvent.time,
    ...                                   anEvent.char,
    ...                                   anEvent.keysym,
    ...                                   anEvent.keysym_num,
    ...                               str(anEvent.widget )
    ...                               )
    ...     aStringVAR.set( sString )
    ...     print sString
    ... 
    >>> #----VAR_TRACER----------------------------------------[#1]
    >>> def aVAR_TRACER_A( p1_quasiNAME, p2_indexOrEmptyString, p3_accessMODE ):
    ...     print "aVAR_TRACER_A()-called::(on){0:} traced_event({1:})".format( str( p1_quasiNAME ), str( p3_accessMODE ) )
    ...     # ###############=[A]#######
    ...     # < do some task =[A] here >
    ...     # ###############=[A]#######
    ...     print "aVAR_TRACER_A()         [{0:}]".format(   str( root.globalgetvar( p1_quasiNAME ) ).replace( " ", "" ) )
    ...

    >>> #----VAR_TRACER----------------------------------------[#2]
    >>> def aVAR_TRACER_B( p1_quasiNAME, p2_indexOrEmptyString, p3_accessMODE ):
    ...     print "aVAR_TRACER_B()-called::(on){0:} traced_event({1:})".format( str( p1_quasiNAME ), str( p3_accessMODE ) )
    ...     # ###############=[B]#######
    ...     # < do some task =[B] here >
    ...     # ###############=[B]######
    ...     print "aVAR_TRACER_B()         [{0:}]".format(   str( root.globalgetvar( p1_quasiNAME ) ).replace( " ", "" ) )
    ... 

    >>> #-----VAR_A_tracer_ID------------------------------"w" EVENT SNIFFER
    >>> aTraceVAR_A_tracer_ID = aStringVAR.trace_variable( "w", aVAR_TRACER_A )

    >>> #-----VAR_B_tracer_ID------------------------------"w" EVENT SNIFFER
    >>> aTraceVAR_B_tracer_ID = aStringVAR.trace_variable( "w", aVAR_TRACER_B )

    >>> #-----------tracer_ID values for ev. theirs resp. de-activation:
    >>> aTraceVAR_A_tracer_ID
    '3071960124LaVAR_TRACER_A'
    >>> aTraceVAR_B_tracer_ID
    '3071961284LaVAR_TRACER_B'

    >>> #---.bind()-----------------------EventHANDLER with a system event <KeyPress>
    >>> root.bind( "<KeyPress>", aKeyPressEventHANDLER ) # <-since here LIVE (!)
    '3071841740LaKeyPressEventHANDLER'
    >>> #------------------------------------------------^^^ since here, it went live
    >>> #                                                 1: having put a mouse on tk-window,
    >>> #                                                 2: set-focus by click
    >>> #                                                 3: started keys:
    >>> #                                                    ( "a",
    >>> #                                                       6-on-<NumKeyPad>,
    >>> #                                                       *-on-<NumKeyPad>

    >>> # this happened "independently, at the same time" ( see time (=@=):: values )
    >>> 

    aVAR_TRACER_B()-called::(on)PY_VAR0 traced_event(w)
    aVAR_TRACER_B()         [[KEY]::a<s/n>::832(=@=)::88486992^from::(.)]
    aVAR_TRACER_A()-called::(on)PY_VAR0 traced_event(w)
    aVAR_TRACER_A()         [[KEY]::a<s/n>::832(=@=)::88486992^from::(.)]
    [KEY]::         a
    <s/n>::       832
    (=@=)::  88486992
    ^from::(.)
    aVAR_TRACER_B()-called::(on)PY_VAR0 traced_event(w)
    aVAR_TRACER_B()         [[KEY]::KP_6<s/n>::832(=@=)::88509107^from::(.)]
    aVAR_TRACER_A()-called::(on)PY_VAR0 traced_event(w)
    aVAR_TRACER_A()         [[KEY]::KP_6<s/n>::832(=@=)::88509107^from::(.)]
    [KEY]::      KP_6
    <s/n>::       832
    (=@=)::  88509107
    ^from::(.)
    aVAR_TRACER_B()-called::(on)PY_VAR0 traced_event(w)
    aVAR_TRACER_B()         [[KEY]::KP_Multiply<s/n>::832(=@=)::88541180^from::(.)]
    aVAR_TRACER_A()-called::(on)PY_VAR0 traced_event(w)
    aVAR_TRACER_A()         [[KEY]::KP_Multiply<s/n>::832(=@=)::88541180^from::(.)]
    [KEY]::KP_Multiply
    <s/n>::       832
    (=@=)::  88541180
    ^from::(.)

这篇关于如何同时独立运行 zmq 和其他 while True: ?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆