読者です 読者をやめる 読者になる 読者になる

日々精進

aikoと旅行とプログラミングと

新たなスレッドを作成するpthread関数群メモ

今回はPOSIXが標準化したスレッドを扱うインターフェイス群の使い方をメモ。コンパイルするときは、-pthreadオプションをお忘れなく。

スレッドの作成

pthread_create関数

書式
#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg);
  • 第一引数:スレッドの起動が成功するとpthread_createが値(スレッド識別子)を設定する。
  • 第二引数:スレッドの属性を設定する。NULLにするとデフォルトが設定される。
  • 第三引数:スレッドが起動する関数。
  • 第四引数:関数に渡す引数  

    概要

    pthread関数は呼び出したプロセス内に新しいスレッドを作成する。start_routine関数を呼び出すことでスレッドは開始される。終了条件は

  • スレッドがpthread_exit関数を呼び出す

  • start_routineから返る
  • スレッドがキャンセルされる
  • プロセス内のいずれかのスレッドで exit(3) が呼ばれるか、 メインスレッドで main() 内で return が実行される

のいずれかである。

返り値

返り値は成功すると0でエラーの場合はエラー番号が返る。

他のスレッドの終了を待つ

pthread_join関数

書式
#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);
  • 第一引数:スレッド識別子
  • 第二引数:対象のスレッドの終了ステータスが格納される
概要

threadで指定したスレッドの終了を待つ。ただしそのスレッドはjoin可能でなければならない(detachされていない)。そのスレッドがすでに終了している場合、 pthread_join() はすぐに返る。合流可能なスレッドが終了しても、 別のスレッドがそのスレッドに対して pthread_join を呼び出すまではリソースが開放されない。

返り値

返り値は成功すると0でエラーの場合はエラー番号が返る。

スレッドを終了する

pthread_exit関数

書式
#include <pthread.h>

void pthread_exit(void *retval);
  • 第一引数:pthread_koinで参照したい値
概要

pthread_exit() 関数は、呼び出したスレッドを終了し、 retval 経由で値を返す。通常は呼び出し先で使う事でスレッドを終了させる。

返り値

この関数は呼び出し側には返らない。

スレッドを切り離す

pthread_detach関数

書式
#include <pthread.h>

int pthread_detach(pthread_t th);
  • 第一引数:スレッド識別子
概要

thread で識別されるスレッドにdetachという印をつける。スレッドthのリソースを即座に開放する。

返り値

成功すると 0 が返る。エラーの場合は、非 0 のエラーコードが返る。

実装例

threadを使ってループ分アスタリスクを代入し、main()で表示する

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

#define N 100

void *thread(void *arg){
  int i=0;
  char *str;
  
  str = (char *)malloc(sizeof(char) * (N+1));
  
  while(i<N){
    printf("thread\n");
    str[i] = '*';
    i++;
  }
  
  str[N] = '\0';
  pthread_exit(str);
}

int main(){
  pthread_t th;
  void *th_return;

  pthread_create(&th, NULL, thread, (void *)NULL);
  
  pthread_join(th, &th_return);
  printf("%s\n",th_return);

  free(th_return);

  return 0;
}