pthreadの使い方
pthreadについて理解したことのメモ
pthreadとは
POSIXスレッドとはスレッドのPOSIX標準である。
スレッド生成やスレッド操作のApiを定義している。
POSIXスレッド - Wikipedia
・・・つまりマルチスレッドプログラミングができるようになります。
新しいスレッドを作成する
pthread_create()関数を使います。
int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
2つめのAttribute引数の意味はよく分かっていませんが、NULLを指定することでデフォルトとなるようです。
#include <stdio.h> #include <pthread.h> #include <sys/types.h> void *thread_func(void *param) { printf("thread_func started\n"); } int main(int argc, char *argv[]) { pthread_t thread; int ret = 0; ret = pthread_create(&thread, NULL, thread_func, NULL); if (ret != 0) { printf("pthread_create() failed.\n"); } printf("pthread_create() called.\n"); pthread_join(thread, NULL); // threadの終了を待つ. return 0; }
出力
>./a.out pthread_create() called. thread_func started
main関数でpthread_create()でthreadを作成、指定したthread_funcが呼び出されています。
排他
スレッドの排他を実現するためにmutex(MUTual EXclusion)が用意されています。
int pthread_mutex_lock(pthread_mutex_t &mutex) int pthread_mutex_unlock(pthread_mutex_t &mutex)
mutexでロックされている区間では同時に1つのスレッドしか操作ができません。
ロックしたら必ずアンロックもセットで行います。
pthread_mutex_t mymutex; void process(void) { pthread_mutex_lock(&mymutex); // 何か処理. pthread_mutex_unlock(&mymutex); }
あるスレッドにてmymutexがロックされている間
他のスレッドはmymutexのロックの取得ができないため
pthread_mutex_lockで待ち状態になります。
条件変数
mutex区間で何か条件の成立を待ちたい、そんなときはpthread_cond_wait()を使用します。
mutexのlock/unlockと同じように
pthread_cond_signal()(またはpthread_cond_broadcast())とセット使用します。
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) int pthread_cond_signal(pthread_cond_t *cond);
これがめちゃ難解でした(のでこれを書いている)。
まず条件の成立を待つ側はpthread_cond_wait(&mycond, &mymutex)を呼び出します。
pthread_cond_wait()は呼ばれるとまず最初にmymutexのロックを解除します。
こうして他のスレッドがmymutex区間にアクセスできるようにします。
そして条件mycondを待ちます。
ここでmymutexのロックが解除されているので
別のスレッドはmymutexのロックを取得して処理を行います。
それによってmycondが成立した場合にpthread_cond_signal(&mycond)を呼び出します。
するとmycondを待っている最初のスレッドがこの時点で目覚めます。
またこのときpthread_cond_wait()はmymutexのロックを再取得します。
mymutexのロックが取得できた後に初めて応答し、最初のスレッドの処理を続行させます。
// スレッド1がmymutexのロックを取得 pthread_mutex_lock(&mymutex); // ある条件が整うまで以下を呼び出し待つ // ここでmymutexのロックは解除される(pthread_mutex_unlock(&mymutex)が実行される) pthread_cond_wait(&mycond, &mymutex); // スレッド2がある条件を成立させたのでスレッド1を起こす // このときpthread_cond_waitはpthread_mutex_lock(&mymutex)が可能になるまで応答しない pthread_cond_signal(&mycond);
こちらを参考にしました。
一般的なスレッド: POSIX スレッドの説明: 第3回