首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Python中只执行一个特定函数的多线程/多进程?

如何在Python中只执行一个特定函数的多线程/多进程?
EN

Stack Overflow用户
提问于 2015-08-15 17:17:02
回答 1查看 789关注 0票数 4

我正在运行一个控制机器人的Python脚本,但是我对如何多线程这个运动控制功能有点困惑。

问题是,在设计硬件时,除非电机控制功能有几个睡眠,否则电机不会移动,因为硬件需要时间将电信号发送到电机。由于这些睡眠在电机控制功能,整个程序停止和停止读取传感器数据。

我想要做的是知道如何在调用电机控制函数时进行多线程/多进程处理,但是一旦程序在循环的下一次迭代中再次命中调用,它就会检查电机控制是否仍在运行(也就是说,它不是通过睡眠完成的)。如果它仍在运行,它只需跳过电机控制调用,然后继续循环、读取传感器数据,然后再次检查电机控制功能是否仍在运行。当然,如果电机控制功能不再运行,我希望它再次被调用。

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

我试过使用concurrent.futures导入,但是收到消息说它不受支持,并且我找不到任何与我打算使用它的方式不同的用法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-16 11:18:54

我认为你不需要线程,但我可能误解了你的需求,所以我将提出两个备选方案。

  1. 不用穿线睡觉

假设您当前的程序流程是这样的:

代码语言:javascript
复制
while True:
    data = read_sensors()
    command = process(data)
    motor_do(command)
    time.sleep(delay)

然后您就可以删除睡眠,只有在最后一次调用是至少几秒钟前的motor_do时才调用delay

代码语言:javascript
复制
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
  1. 使用线程(这是一个示例,我没有使用python 2.7进行线程/异步操作的经验,因此可能有更好的方法来做到这一点)

假设您当前的程序流程是这样的:

代码语言:javascript
复制
while True:
    data = read_sensors()
    command = process(data)
    motor_do(command) // this function sleeps and you CANNOT change it

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

代码语言:javascript
复制
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().除非系统时钟被更改:“虽然此函数通常返回非递减值,但如果在两个调用之间设置了系统时钟,则返回的值可能低于以前的调用。”(Python2.7 doc)

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

关于unix/py2.7上的精确时间延迟,请参见How do I get monotonic time durations in python? ( time()可能有用)

Python3 :只要用time.monotonic()..。或time.perf_counter().

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32027233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档