Python中的并行函数解决延迟

时间:2017-12-11 09:20:09

标签: python parallel-processing multiprocessing delay

我知道以前可能会问过类似的问题。但我找不到适合我情况的解决方案。提前为这个愚蠢的问题道歉。

我正在从USB集线器(连接到两个传感器)读取两个电压值。问题是,我的代码的方式,将有一个约。它们之间有0.8秒的延迟,所以我永远不能同时拥有它们的两个值(如果我减少两个time.sleep()中的任何一个,则不会报告第二个def的值)。我想如果两者都可以同时运行,也许我可以拥有属于完全相同时间点的值,而不会随时间移动。如果您有任何可以改进此代码的评论,我会很感激 我提前感谢您的意见。

            import sys
            import time
            import datetime
            from Phidget22.Devices.VoltageRatioInput import *
            from Phidget22.PhidgetException import *
            from Phidget22.Phidget import *
            from Phidget22.Net import *
            fig = plt.figure()
            ax1 = fig.add_subplot(1,1,1)
            try:
                ch = VoltageRatioInput()
            except RuntimeError as e:
                print("Runtime Exception %s" % e.details)
                print("Press Enter to Exit...\n")
                readin = sys.stdin.read(1)
                exit(1)

            a=[]
            b=[]
            try:
                start = time.time()
                while True:
                    def VoltageRatioChangeHandler(e, voltageRatio):
                        n=voltageRatio
                        a.append(n)


                    ch.setOnVoltageRatioChangeHandler(VoltageRatioChangeHandler)
                    ch.setHubPort(1)
                    ch.setIsHubPortDevice(1)
                    ch.openWaitForAttachment(5000)

                    if(ch.getChannelSubclass() == ChannelSubclass.PHIDCHSUBCLASS_VOLTAGERATIOINPUT_BRIDGE):
                        ch.setBridgeEnabled(1)

                    time.sleep(0.3)
                    ch.close()
                    end1 = time.time()
                    Elt1 = end1-start
                    print (Elt1)
                    print a
            ###    
                    def VoltageRatioChangeHandler(e, voltageRatio2):
                        m=voltageRatio2
                        if m is None:
                            b.append(0)
                        else:
                            b.append(m)

                    ch.setOnVoltageRatioChangeHandler(VoltageRatioChangeHandler)
                    ch.setHubPort(0)
                    ch.setIsHubPortDevice(0)
                    ch.openWaitForAttachment(5000)

                    if(ch.getChannelSubclass() == ChannelSubclass.PHIDCHSUBCLASS_VOLTAGERATIOINPUT_BRIDGE):
                        ch.setBridgeEnabled(1)

                    time.sleep(0.4)
                    ch.close()
                    end = time.time()
                    Elt = end - start
                    print (Elt)
                    print b


            except KeyboardInterrupt:
                print ("gracefully aborted")
                sys.exit()

1 个答案:

答案 0 :(得分:0)

并行声音easier than done. (... watch the [us] lost here )
最好不要以这种方式移动,但是:

长话短说:“平行”的成本对您的用例来说是毁灭性的。

同样重新发明一个轮子是非常昂贵的,所以让我给你一个概念,这个概念几乎免费并且像魅力一样。

您的测量结果与多智能体控制系统非常接近,所以让我们重新使用完全出于同样原因开发的框架 - MVC(是的,一个焦虑和好主意,就像一个起源于XEROX Palo Alto研究中心着名的智慧思想家。

import Tkinter as tk # YESSSS! re-using a GUI-tool ( i.e. multi-agent by-design )

关键价值在于“概念控制器”部分“设计自由”,使用内置的所有非常精心打磨的工具,而不是打扰低级细节。

高层次的想法:(一个完整的感知网络控制计划可能会这样)

让传感器按照您的需要随时阅读(只需通过常识,理性气味或实验控制环稳定性理论的严格奈奎斯特边界来驱动)。 p>

首先,我们可能需要一种方法,如何被动地读取一对值(同时一致地读取(好吧,更好地使用一个共同的时间窗口,对吗?)。

SENSOR_A_Last_Voltage_Value = tk.DoubleVar()
SENSOR_B_Last_Voltage_Value = tk.DoubleVar()

SCHEDULED_EVENT_READ_A      = tk.StringVar()
SCHEDULED_EVENT_READ_B      = tk.StringVar()

SIGNAL_2_READ_Voltage_Value = tk.IntVar()

如果您愿意,这些是MVC模型部分智能“寄存器”。

def aSensorREAD_A():
    #--------------------------------------------------
    # handle all the tricks to read a given sensor ONCE
    #--------------------------------------------------
    ...
    ch.setHubPort( 0 )
    ch.setIsHubPortDevice( 0 )
    ch.openWaitForAttachment( 5000 )
    ...
    a_just_read_value = ...

    #--------------------------------------------------
    # Let the MVC-framework store this value into MODEL
    #--------------------------------------------------
    SENSOR_A_Last_Voltage_Value.set( a_just_read_value )

    #--------------------------------------------------
    # schedule a ( self-operated ) read "next" ONCE
    #--------------------------------------------------
    SCHEDULED_EVENT_READ_A.set( root.after( 100, aSensorREAD_A ) )
    # repeat                         after  100 [ms]
    #
    # a cool way to command actually your Boss, isn't it?
    # + may,
    # if at need, root.after_cancel( SCHEDULED_EVENT_READ_A )

因此,我们可能会认为SensorREAD_*()的角色是这样一个独立的代理人,负责用实际的传感器读数做低级别的工作。

对于被动的价值消费者,只会有一对“智能”变量,它们被授予始终携带更新的(最后读取)值。

print( "[A] {0: >16.3f}[mV]".format( SENSOR_A_Last_Voltage_Value.get() )
print( "[B] {0: >16.3f}[mV]".format( SENSOR_B_Last_Voltage_Value.get() )

对于触发预期的价值消费者,可能还有一个额外的工具,可以通知任何这样的触发期待读者。

idTrA1 = SENSOR_A_Last_Voltage_Value.trace_variable( "w", aTriggerdFUN1ToCallOnA )
idTrA2 = SENSOR_A_Last_Voltage_Value.trace_variable( "w", aTriggerdFUN2ToCallOnA )
idTrA3 = SENSOR_A_Last_Voltage_Value.trace_variable( "w", aTriggerdFUN3ToCallOnA )

idTrB1 = SENSOR_B_Last_Voltage_Value.trace_variable( "w", aTriggerdFUN1ToCallOnB )
...
idTrB7 = SENSOR_B_Last_Voltage_Value.trace_variable( "w", aTriggerdFUN7ToCallOnB )
# as one may wish and need

最后但并非最不重要的是,可能还有另一种连贯阅读策略:

SIGNAL_2_READ_Voltage_Value = tk.IntVar()                       # MVC-Model "register"

idTrSIG2R_A = SIGNAL_2_READ_Voltage_Value( "w", aSensorREAD_A ) # MVC-Controller actor
idTrSIG2R_B = SIGNAL_2_READ_Voltage_Value( "w", aSensorREAD_B )

这使得一个外部的触发读取工具,实际上有助于“触发”“同时”读取,只需触摸:

SIGNAL_2_READ_Voltage_Value.set( 1 + SIGNAL_2_READ_Voltage_Value.get() )

优雅终止的最后一步也是明确而诚实的:

finally:
    #---------------------------------------------------
    SIGNAL_2_READ_Voltage_Value.trace_vdelete( "w", idTrSIG2R_A )
    SIGNAL_2_READ_Voltage_Value.trace_vdelete( "w", idTrSIG2R_B )
    #---------------------------------------------------
    SENSOR_A_Last_Voltage_Value.trace_vdelete( "w", idTrA1 )
    SENSOR_A_Last_Voltage_Value.trace_vdelete( "w", idTrA2 )
    SENSOR_A_Last_Voltage_Value.trace_vdelete( "w", idTrA3 )
    #---------------------------------------------------
    SENSOR_B_Last_Voltage_Value.trace_vdelete( "w", idTrB1 )
    ...
    SENSOR_B_Last_Voltage_Value.trace_vdelete( "w", idTrB7 )

For more details and mock-up case inspiration may like to read this