如何在Python中多线程/多处理一个特定函数的一个实例?

我正在运行一个控制机器人的Python脚本,但我对如何多线程控制电机控制功能感到困惑.

问题在于硬件的设计使得电机不会移动,除非电机控制功能中存在多个休眠,因为硬件需要时间将电信号发送到电机.由于电机控制功能中的这些休眠,整个程序停止并停止读取传感器数据.

我想做的是知道如何在调用电机控制功能后对其进行多线程/多处理,但是一旦程序在循环的下一次迭代中再次遇到调用,它会检查电机控制是否仍在运行(即睡眠没有完成.如果它仍在运行,它只是跳过电机控制调用并继续循环,读取传感器数据,然后再次检查电机控制功能是否仍在运行.当然,如果电机控制功能不再运行,我希望再次调用它.

基本上,整个程序只需要两个线程:一个运行主程序,一个分支关闭,并在每次电机控制功能完成执行时连续重新运行一个电机控制功能实例.

我曾尝试使用concurrent.futures导入,但得到消息说它不受支持,我找不到任何特定于我打算使用它的方式的用法.

解决方法:

我认为你不需要线程,但我可能会误解你的要求,所以我将提出2个替代方案.

>没有线程和睡眠

假设您当前的程序流程如下:

while True:
    data = read_sensors()
    command = process(data)
    motor_do(command)
    time.sleep(delay)

然后你可以删除睡眠,如果最后一次呼叫至少延迟几秒钟,则只调用motor_do.

last_call_time = -delay # to be sure that motor_do can be called the first time
# "On Windows, [time.clock] returns wall-clock seconds elapsed since the first call to this
# function, as a floating point number, based on the Win32 function QueryPerformanceCounter()
# The resolution is typically better than one microsecond." (python 2.7 doc)
# i.e. close to 0 on first call of time.clock()

while True:
    data = read_sensors()
    command = process(data)
    motor_try(command)

def motor_try(command):
    global last_call_time

    current_time = time.clock()
    # on win that works, on unix... you may want to take a look at the NB

    elapsed = current_time - last_call_time
    if elapsed >= delay:
        motor_do(command)
        last_call_time = current_time

>使用线程(这是一个例子,我没有使用python 2.7进行线程/异步的经验,所以可能有更好的方法来做到这一点)

假设您当前的程序流程如下:

while True:
    data = read_sensors()
    command = process(data)
    motor_do(command) // this function sleeps and you CANNOT change it

然后你必须启动1个线程,它只会异步地将命令推送到电机.

import thread

command = None
command_lock = thread.allocate_lock()

def main():
    thread.start_new_thread(motor_thread)

    global command
    while True:
        data = read_sensors()
        with command_lock:
            command = process(data)

def motor_thread():
    while True:
        while not command: # just to be sure
            time.sleep(0.01)
            # small delay here (for instance, the time consumed by read_sensors + process)
        with command_lock:
            motor_do(command)
            command = None
        time.sleep(delay)

注意:在Unix上,time.clock()返回处理器时间(=没有空闲时间),所以最好使用time.time()…除非更改系统时钟:“此函数通常返回非 – 如果在两次调用之间设置了系统时钟,则它可以返回比前一次调用更低的值.“ (python 2.7 doc)

我不知道time.sleep()对系统时钟变化的反应.

有关unix / py2.7的精确时间延迟,请参阅How do I get monotonic time durations in python?(Understanding time.perf_counter() and time.process_time()可能很有用)

Python3:只使用time.monotonic()…或time.perf_counter().

上一篇:2021-01-08


下一篇:MATLAB Robotics Toolbox(Release 10)模块库--总结(一)