parent
1c73cd77ed
commit
881a36e666
1 changed files with 125 additions and 0 deletions
@ -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 <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) */ |
||||
Loading…
Reference in new issue