信号量の理解例

4564 ワード

信号量は信号灯とも呼ばれ、異なるプロセス間のデータオブジェクトを調整するために使用され、最も主要な応用は共有メモリ方式のプロセス間通信である.本質的に信号量はカウンタであり共有メモリなどのリソースへのアクセス状況を記録するために使用されます.一般的に、共有リソースを取得するには、プロセスは、(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#