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