Arduinoで遊ぶページ
Arduinoで遊んだ結果を残すページです
pthread
ESP32

概要

Arduino core for the ESP32を使った、ESP-WROOM-32開発ボードのpthreadの実験です。マルチタスクについての実験も併せてご覧ください。

Arduino core for the ESP32のインストールのページはこちら

実験

pthread_create()

単純に、pthread_create()した後、pthread_join()するだけのものです。スレッドの中では、タスク名称とどのコアで動いているかを表示させてみました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <pthread.h>
 
void *printThreadInfo(void *id) {
  Serial.printf("Thread %d(%s) runs on core %d\n", (int)id, pcTaskGetTaskName(NULL), xPortGetCoreID());
 
  return NULL;
}
 
void setup() {
  // put your setup code here, to run once:
  const int numThread = 10;
  pthread_t threads[numThread];
  int status;
 
  Serial.begin(115200);
 
 
  for (int i = 0; i < numThread; i++) {
    if (pthread_create(&threads[i], NULL, printThreadInfo, (void *)i)) {
      Serial.printf("Thread %d error.\n", i);
    }
  }
 
  for (int i = 0; i < numThread; i++) {
    if (pthread_join(threads[i], (void**)&status) == 0) {
      Serial.printf("Thread %d join success. status = %d\n", i, status);
    } else {
      Serial.printf("Thread %d join failure.\n", i);
    }
  }
}
 
void loop() {
  // put your main code here, to run repeatedly:
 
}

プログラムの実行結果は以下の通りです。タスクの名称は"pthread"となっていて、pthreadが実行されているコアは、適当に割り振られているようです。

https://github.com/espressif/esp-idf/blob/master/components/pthread/pthread.cに、pthread_create()のソースがあったので、見てみました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg)
{
    TaskHandle_t xHandle = NULL;
 
    ESP_LOGV(TAG, "%s", __FUNCTION__);
    if (attr) {
        ESP_LOGE(TAG, "%s: attrs not supported!", __FUNCTION__);
        return ENOSYS;
    }
    esp_pthread_task_arg_t *task_arg = malloc(sizeof(esp_pthread_task_arg_t));
    if (task_arg == NULL) {
        ESP_LOGE(TAG, "Failed to allocate task args!");
        return ENOMEM;
    }
    memset(task_arg, 0, sizeof(esp_pthread_task_arg_t));
    esp_pthread_t *pthread = malloc(sizeof(esp_pthread_t));
    if (pthread == NULL) {
        ESP_LOGE(TAG, "Failed to allocate pthread data!");
        free(task_arg);
        return ENOMEM;
    }
    memset(pthread, 0, sizeof(esp_pthread_t));
    task_arg->func = start_routine;
    task_arg->arg = arg;
    BaseType_t res = xTaskCreate(&pthread_task_func, "pthread", CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT,
        task_arg, CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT, &xHandle);
    if(res != pdPASS) {
        ESP_LOGE(TAG, "Failed to create task!");
        free(pthread);
        free(task_arg);
        if (res == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) {
            return ENOMEM;
        } else {
            return EAGAIN;
        }
    }
    pthread->handle = xHandle;
 
    if (xSemaphoreTake(s_threads_mux, portMAX_DELAY) != pdTRUE) {
        assert(false && "Failed to lock threads list!");
    }
    SLIST_INSERT_HEAD(&s_threads_list, pthread, list_node);
    xSemaphoreGive(s_threads_mux);
 
    // start task
    xTaskNotify(xHandle, 0, eNoAction);
 
    *thread = (pthread_t)pthread; // pointer value fit into pthread_t (uint32_t)
 
    ESP_LOGV(TAG, "Created task %x", (uint32_t)xHandle);
 
    return 0;
}

タスクは、xTaskCreate()を使って生成されており、タスク名称は固定で"pthread"となっていました。実験の結果通りです。

その他

pthead_exit()を使おうとしたところ、“undefined reference to `pthread_exit’” と言われてしまいました。

バージョン

Hardware:ESP-WROOM-32
Software:Arduino 1.8.4/Arduino core for the ESP32

最終更新日

June 20, 2020

inserted by FC2 system