信号量の理解例
信号量は信号灯とも呼ばれ、異なるプロセス間のデータオブジェクトを調整するために使用され、最も主要な応用は共有メモリ方式のプロセス間通信である.本質的に信号量はカウンタであり共有メモリなどのリソースへのアクセス状況を記録するために使用されます.一般的に、共有リソースを取得するには、プロセスは、(1)リソースを制御する信号量をテストする必要があります.(2)信号量の値が正の場合、そのソースの使用を許可します.プロセスは、信号量を1に減らします.(3)この信号量が0の場合、このリソースは現在使用できなくなり、プロセスはスリープ状態に入り、信号量値が0より大きくなるまでプロセスが起動し、ステップ(1)に移行する.(4)プロセスが信号量制御のリソースを1つも使用しなくなった場合、信号量値に1を加算する.このとき、プロセスがスリープ中でこの信号量を待っている場合、このプロセスを起動する.
実行結果:
/***************************************
* @file sem_test.c
***************************************/
// gcc sem_test.c -o sem_test -lpthread
#include
#include
#include
#include
#include
#include
#define WORK_SIZE 1024 //
char work_area[WORK_SIZE];
sem_t bin_semA;
sem_t bin_semB;
void *thread_functionA(void * arg);
void *thread_functionB(void * arg);
int main(int argc,char * argv [ ])
{
int ret ;
void* thread_result;
pthread_t threadA;
pthread_t threadB;
ret = sem_init(&bin_semA,0, 0); // 0
if (ret != 0) {
perror("semA_init() is failed!
");
exit(EXIT_FAILURE);
}
ret = sem_init(&bin_semB,0, 0); // 0
if (ret != 0) {
perror("semB_init() is failed!
");
exit(EXIT_FAILURE);
}
ret = pthread_create(&threadA, NULL, thread_functionA, NULL);
if (ret != 0) {
perror("threadA create failed!
");
exit(EXIT_FAILURE);
}
ret = pthread_create(&threadB, NULL, thread_functionB, NULL);
if (ret != 0) {
perror("threadB create failed!
");
exit(EXIT_FAILURE);
}
int i=0;
printf("Enter 'end' to finish!
");
while (strncmp("end", work_area, 3) != 0) {
fgets(work_area, WORK_SIZE, stdin);
for (i=0;i<2;i++){ //
sem_post(&bin_semA); // + 1
}
sem_post(&bin_semB); // + 1
}
printf("Waitint for threadA join
");
ret = pthread_join(threadA, &thread_result);
if (ret != 0) {
perror("threadA_join failed!
");
exit(EXIT_FAILURE);
}
printf("Waitint for threadB join
");
ret = pthread_join(threadB, &thread_result);
if (ret != 0) {
perror("threadB_join failed!
");
exit(EXIT_FAILURE);
}
printf("thread join()
");
sem_destroy(&bin_semA);
sem_destroy(&bin_semB);
exit(EXIT_FAILURE);
}
void *thread_functionA(void * arg){
sem_wait(&bin_semA); // - 1
printf("thread_functionA first acquire sem
");
while (strncmp("end", work_area,3) != 0){
printf("thread_functionA get input %s
", work_area);
sem_wait(&bin_semA); // - 1
printf("thread_functionA acquire sem
");
}
pthread_exit(NULL);
}
void *thread_functionB(void * arg){
sem_wait(&bin_semB); // - 1
printf("thread_functionB first acquire sem
");
while (strncmp("end", work_area,3) != 0){
printf("thread_functionB get input %s
", work_area);
sem_wait(&bin_semB); // - 1
printf("thread_functionB acquire sem
");
}
pthread_exit(NULL);
}
実行結果:
root@ql-Ubuntu:~/my_test# ./sem_test
Enter 'end' to finish!
hello
thread_functionB first acquire sem
thread_functionB get input hello
thread_functionA first acquire sem
thread_functionA get input hello
thread_functionA acquire sem
thread_functionA get input hello
world
thread_functionB acquire sem
thread_functionB get input world
thread_functionA acquire sem
thread_functionA get input world
thread_functionA acquire sem
thread_functionA get input world
end
Waitint for threadA join
thread_functionB acquire sem
thread_functionA acquire sem
Waitint for threadB join
thread join()
root@ql-Ubuntu:~/my_test#