多執行緒

本來我們的程式一次只能執行一行,如果要一次執行兩行就必須開多執行緒,例如有兩個迴圈需要同時執行,或是等待網路資料進來的同時又要處理感測元件收到的資料。換句話說,當有兩件工作要同時進行時,就要開執行緒才能辦到。Pico 或 Pico W 的 CPU 是雙核心 CPU,所以可以再多開一個執行緒,讓兩個核心能同時執行程式碼。在沒有建立執行緒前,原本程式都是在「主執行緒」中執行,建立新的執行緒後,就可以將一部分程式碼搬到新執行緒去。簡單的範例如下,這段程式碼執行後會看到 A、B 同時印出。

## Documents
## https://mpython.readthedocs.io/en/master/library/micropython/_thread.html
import _thread

def new_thread():
    for _ in range(10):
        print('A')

def main_thread():
    for _ in range(10):
        print('B')
    
_thread.start_new_thread(new_thread, ()) 
main_thread()

start_new_thread() 的第二個參數目前放了一個空的 tuple,這是用來傳資料到執行緒的位置,需要傳資料時可以這樣使用:

def new_thread(char, times):
    for _ in range(times):
        print(char)

_thread.start_new_thread(new_thread, ('M', 3)) 

執行緒間的資料交換

由於執行緒會共享記憶體,所以主執行緒與新執行緒要交換資料很容易,透過全域變數就可以了。例如下面這個範例,透過全域變數 sum 做資料交換,最後在主執行緒中印出 55,這是在新執行緒中計算 1 + 2 + 3 + … + 10 的程式。

import _thread
import utime

sum = 0
def new_thread(n):
    global sum
    for i in range(n):
        sum += i

def main_thread():
    utime.sleep(1)
    print(sum)
    
_thread.start_new_thread(new_thread, (11,)) 
main_thread()

練習

  1. 同時處理兩個感測元件收進來的資料,例如兩個按鈕分別控制兩個 LED 燈亮滅。
  2. 將 MQTT 的訂閱與發佈分別放在兩個不同的執行緒中執行。目前訂閱者只能放在主執行緒,原因不明。

★本系列收錄於「第一次就上手」選單

發表迴響