期限 2026-05-25 17:00
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

125 lines
3.5 KiB

/* 1-Producer 1-Consumer Problem (pthread)
Env.:
・Cygwin (もしくはPOSIX準拠のコンパイル・実行環境)
Compile:
% gcc sem01.c -o sem01 -lpthread
Exec:
% ./sem01
Note:
・TODO (2カ所) のコードを埋めてからコンパイル・実行すること
・使用した関数の意味や使い方は各自で調べ、理解すること
・threadに与えるデータ(動作停止時間)を変え、動作を確認すること
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <semaphore.h> /* for POSIX semaphore */
#include <pthread.h> /* for POSIX thread */
#include <time.h>
#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) */