この記事は全然ダメだったようです。
こちらに新しく書き直しました。
http://d.hatena.ne.jp/amachang/20080617/1213694238
こんな感じになった
#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <pthread.h> static int* q; static int n; // 次に入れるインデックス static int l; // 次に出すインデックス static int s; static pthread_mutex_t m; static pthread_cond_t c; void initQ (size_t size) { n = 0; l = 0; s = size; // キューの領域確保 q = (int*)malloc(s * sizeof(int)); // -1 は空の意味 memset(q, -1, s * sizeof(int)); // ミューテックスと cond の初期化 pthread_mutex_init(&m, NULL); pthread_cond_init(&c, NULL); } void destroyQ () { // キューの解放 free(q); // ミューテックスと cond の解放 pthread_mutex_destroy(&m); pthread_cond_destroy(&c); } void enQ (int data) { // ロック pthread_mutex_lock(&m); // キューが空いてれば if (q[n % s] == -1) { // キューにデータを入れる q[n++ % s] = data; printf("thread[%p]: enQ(%d)\n", pthread_self(), data); // ロック解除 pthread_mutex_unlock(&m); // データが入ったよ!と待ちスレッドに通知 pthread_cond_signal(&c); // 実行権をゆずるくん sleep(0); // pthread_yield(); } // キューがいっぱい else { // ロック解除 pthread_mutex_unlock(&m); // 実行権をゆずるくん sleep(0); // pthread_yield(); // もっかい挑戦 enQ(data); } } int deQ () { // ロック pthread_mutex_lock(&m); // データが入るまで待ちまくる while (q[l % s] == -1) pthread_cond_wait(&c, &m); // データを取る int r = q[l %s]; q[l++ % s] = -1; printf("thread[%p]: deQ(%d)\n", pthread_self(), r); // ロック解除 pthread_mutex_unlock(&m); return r; }
実行してみる
main を作って
void* thread_enQ(void* p) { while(1) { enQ((int)p); } } void* thread_deQ(void* p) { while(1) { deQ(); } } int main (int argc, char** argv) { initQ(10); pthread_t t0; pthread_t t1; pthread_create(&t0, NULL, thread_enQ, (void*)0); pthread_create(&t1, NULL, thread_enQ, (void*)1); pthread_t t2; pthread_t t3; pthread_create(&t2, NULL, thread_deQ, NULL); pthread_create(&t3, NULL, thread_deQ, NULL); pthread_join(t0, NULL); destroyQ(); return 0; }
実行!
$ gcc queue.c && ./a.out thread[0xb0081000]: enQ(0) thread[0xb0185000]: deQ(0) thread[0xb0103000]: enQ(1) thread[0xb0185000]: deQ(1) thread[0xb0081000]: enQ(0) thread[0xb0185000]: deQ(0) thread[0xb0103000]: enQ(1) thread[0xb0185000]: deQ(1) thread[0xb0081000]: enQ(0) thread[0xb0185000]: deQ(0) : :
おおお。できたできた
Mac では
pthread_yield がないと言われた><
なので sleep(0) でやったけどいいのかな