簡體   English   中英

如何在Python中多線程/多處理一個特定函數的一個實例?

[英]How to multithread/multiprocess just one instance of a particular function in Python?

我正在運行一個控制機器人的Python腳本,但我對如何多線程控制電機控制功能感到困惑。

問題在於硬件的設計使得電機不會移動,除非電機控制功能中存在多個休眠,因為硬件需要時間將電信號發送到電機。 由於電機控制功能中的這些休眠,整個程序停止並停止讀取傳感器數據。

我想做的是知道如何在調用電機控制功能后對其進行多線程/多處理,但是一旦程序在循環的下一次迭代中再次遇到調用,它會檢查電機控制是否仍在運行(即睡眠沒有完成。 如果它仍在運行,它只是跳過電機控制調用並繼續循環,讀取傳感器數據,然后再次檢查電機控制功能是否仍在運行。 當然,如果電機控制功能不再運行,我希望再次調用它。

基本上,整個程序只需要兩個線程:一個運行主程序,一個分支關閉,並在每次電機控制功能完成執行時連續重新運行一個電機控制功能實例。

我曾嘗試使用concurrent.futures導入,但得到消息說它不受支持,我找不到任何特定於我打算使用它的方式的用法。

我認為你不需要線程,但我可能會誤解你的要求,所以我將提出2個替代方案。

  1. 沒有線程和睡眠

假設您當前的程序流程如下:

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

然后你可以刪除睡眠,如果最后一次呼叫至少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
  1. 使用線程(這是一個例子,我沒有使用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()對系統時鍾變化的反應。

請參閱如何在python中獲得單調持續時間? 對於unix / py2.7上的精確時間延遲(以及了解time.perf_counter()和time.process_time()可能很有用)

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM