相互排除変数と条件変数
相互排除変数のロックとアンロックのための関数
#include <pthread.h> int pthread_mutex_lock(pthread_mutex_t *mptr); int pthrea_mutex_trylock(pthread_mutex_t *mptr); int pthread_mutex_unlock(pthread_mutex_t *mptr); 戻り値:関数とも、成功なら0、エラーなら正のExxx値
生産者-消費者問題
条件変数:待ちと通知
pthread_cond_t型の変数を操作するのが、pthread_cond_waitとpthread_cond_signal。
#include <pthread.h> int pthread_cond_wait(pthread_cond_t *cptr,pthread_mutex_t *mptr); int pthread_cond_signal(pthread_cond_t *cptr); 戻り値:関数とも成功なら0、エラーなら正のExxx値
pthread_cond_waitは、
//Producer-Consumer Pettern //生産者-消費者 パターン #include <pthread.h> #include <stdio.h> #define MAX_QUEUE_SIZE 3 int queue[MAX_QUEUE_SIZE]; int head = 0; int tail = 0; int count = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond_cons = PTHREAD_COND_INITIALIZER; pthread_cond_t cond_prod = PTHREAD_COND_INITIALIZER; void enqueue(int n) { pthread_mutex_lock(&mutex); while (count >= MAX_QUEUE_SIZE) { pthread_cond_wait(&cond_prod,&mutex); } queue[tail] = n; tail = (tail + 1) % MAX_QUEUE_SIZE; count++; pthread_cond_signal(&cond_cons); pthread_mutex_unlock(&mutex); } int dequeue() { pthread_mutex_lock(&mutex); while (count <= 0) { pthread_cond_wait(&cond_cons,&mutex); } int elem = queue[head]; head = (head + 1) % MAX_QUEUE_SIZE; count--; pthread_cond_signal(&cond_prod); pthread_mutex_unlock(&mutex); return elem; } void * consumer(void *arg) { int n; for (;;) { n = dequeue(); printf("dequeued :%d\n",n); sleep(2); } return NULL; } void * producer(void *arg) { int i; for (i = 0; ; i++) { enqueue(i); printf("enqueued :%d\n",i); sleep(1); } return NULL; } int main() { int i; pthread_t cons_thread; pthread_t prod_thread; /* Creates threads */ pthread_create(&cons_thread, NULL, consumer, NULL); pthread_create(&prod_thread, NULL, producer, NULL); /* Join threads */ pthread_join(cons_thread, NULL); pthread_join(prod_thread, NULL); printf("Exit!"); return 0; }
条件変数: 制限時間付きの待ちとブロードキャスト
複数のスレッドを起こす場合、pthread_cond_broadcastを用いる。#include <pthread.h> int pthread_cond_broadcast(pthread_cond_t *cptr); int pthread_cond_timedwait(pthread_cond_t *cptr, pthread_mutex_t *mptr, const struct timespec *abstime); 戻り値:2関数とも成功なら0、エラーなら正のExxx値
pthread_cond_timewaitは、呼び出したスレッドがブロックする時間に制限を設けることが出来る。
abstimeは、timespec構造体。
struct timespec { time_t tv_spec; /* 秒 */ long tv_nsec; /* ナノ秒 */ };
abstimeは、絶対時刻であり、時間の差ではない。abstimeには、関数から戻るシステム時刻を指定する。
相互排除変数と条件変数の属性
相互排除変数や条件変数の生成と破壊を行う関数#include <pthread.h> int pthread_mutex_init(pthread_mutex_t *mptr, const pthread_mutexattr_t *attr); int pthread_mutex_destroy(pthread_mutex_t *mptr); int pthread_cond_init(pthread_cond_t *cptr, const pthread_condattr_t *attr); int pthread_cond_destroy(pthread_cond_t *cptr); 戻り値:4関数とも成功なら0、エラーなら正のExxx値