From 881a36e666f24a815eb8b7aea03ea7726be020f2 Mon Sep 17 00:00:00 2001 From: agomizi1cm Date: Mon, 1 Jun 2026 11:08:15 +0900 Subject: [PATCH] =?UTF-8?q?Linux=E5=88=A9=E7=94=A8=E6=BC=94=E7=BF=923?= =?UTF-8?q?=E3=81=AE=E3=82=B5=E3=83=B3=E3=83=97=E3=83=AB=E3=82=B3=E3=83=BC?= =?UTF-8?q?=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sem01-TODO.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 sem01-TODO.c diff --git a/sem01-TODO.c b/sem01-TODO.c new file mode 100644 index 0000000..e9654ba --- /dev/null +++ b/sem01-TODO.c @@ -0,0 +1,125 @@ +/* 1-Producer 1-Consumer Problem (pthread) + +Env.: +・Cygwin (もしくはPOSIX準拠のコンパイル・実行環境) + +Compile: +% gcc sem01.c -o sem01 -lpthread + +Exec: +% ./sem01 + +Note: +・TODO (2カ所) のコードを埋めてからコンパイル・実行すること +・使用した関数の意味や使い方は各自で調べ、理解すること +・threadに与えるデータ(動作停止時間)を変え、動作を確認すること +*/ +#include +#include +#include + +#include /* for POSIX semaphore */ +#include /* for POSIX thread */ +#include + +#define N 8 /* リングバッファサイズ */ +#define LEN 40 /* 生成メッセージ長 */ +sem_t S; /* セマフォ M */ +sem_t M; /* セマフォ S */ +char Buffer[N]; /* リングバッファ用共有メモリ領域 */ + +struct threaddata { + pthread_t th; + struct timespec t; +}; + +void *thread_producer(void *tdata) { + struct threaddata *priv = (struct threaddata *)tdata; + int I = 0; + int count = 0; + char mes; + + while(count<=LEN) { + if((count/10)%2==0) { + mes = '0' + (count % 10); /* メッセージ生成 */ + } else { + mes = 'A' + (count % 10); /* メッセージ生成 */ + } + sem_wait(&S); /* P(S) */ + Buffer[I] = mes; + sem_post(&M); /* V(M) */ + I = ( I + 1 ) % N; + count++; + //printf("producer: [%c] count=%d, I=%d\n",mes,count,I); + nanosleep(&priv->t,NULL); /* 指定時刻だけ実行停止 */ + } + + /* done */ + return (void *) NULL; + +} + +void *thread_consumer(void *tdata) { + struct threaddata *priv = (struct threaddata *)tdata; + int J = 0; + int count = 0; + char mes; + + while(count<=LEN) { + /* TODO: P(M) */ + + mes = Buffer[J]; + + /* TODO: V(S) */ + + J = ( J + 1 ) % N; + //printf("consumer: [%c] count=%d, J=%d\n",mes,count,J); + printf("%c",mes); + count++; + fflush(stdout); + nanosleep(&priv->t,NULL); /* 指定時刻だけ実行停止 */ + } + printf("\n"); + + /* done */ + return (void *) NULL; +} + +int main (void) { + + int r; + struct threaddata data_producer; /* Producerスレッドに渡すデータ */ + struct threaddata data_consumer; /* Consumerスレッドに渡すデータ */ + + /* スレッド初期化 */ + /*** producerの待ち時間 */ + data_producer.t.tv_sec = 0; /* 秒 */ + data_producer.t.tv_nsec = 100*1000*1000; /* ナノ秒 */ + /*** consumerの待ち時間 */ + data_consumer.t.tv_sec = 0; /* 秒 */ + data_consumer.t.tv_nsec = 500*1000*1000; /* ナノ秒 */ + /*** 2種のsemaphorの初期化 */ + sem_init(&S, 0, N); + sem_init(&M, 0, 0); + /*** thread生成 */ + r = pthread_create(&data_producer.th, NULL, thread_producer, (void *) (&data_producer)); + if (r != 0) { + fprintf(stderr, "pthread_create() [%s] failed for %d.", "producer", r); + exit(EXIT_FAILURE); + } + r = pthread_create(&data_consumer.th, NULL, thread_consumer, (void *) (&data_consumer)); + if (r != 0) { + fprintf(stderr, "pthread_create() [%s] failed for %d.", "consumer", r); + exit(EXIT_FAILURE); + } + + /* スレッド終了待ち + 終了処理 */ + pthread_join(data_producer.th, NULL); + pthread_join(data_consumer.th, NULL); + sem_destroy(&S); + sem_destroy(&M); + + exit(EXIT_SUCCESS); + +} +/* EOF (sem01.c) */