关于c:线程间同步信号量控制Semaphore

42次阅读

共计 1455 个字符,预计需要花费 4 分钟才能阅读完成。

上一篇生产者-消费者的例子是基于链表的,其空间能够动态分配,当初基于固定大小的环形
队列重写这个程序,这次不再利用 mutex 而是 semaphore 来实现线程间同步!
上一篇文章链接:https://segmentfault.com/a/11…

仍旧是生产者生产一个构造体串在链表的表头上,消费者从表头取走构造体,生产者未生产或生产的曾经被拿完,则消费者须要挂起期待.

  1 #include <stdlib.h>
  2 #include <pthread.h>
  3 #include <stdio.h>
  4 #include <semaphore.h>
  5 
  6 #define NUM 5
  7 int queue[NUM];
  8 sem_t blank_number, product_number;
  9 
 10 void *producer(void *arg)
 11 {   
 12     int p = 0;
 13     while (1) {14         sem_wait(&blank_number);//wait 能够取得信号,使 init 初始化中 semaphore 值 -1,如果减到 0 则挂起期待,胜利取
    用后持续进行后续操作
 15         queue[p] = rand() % 1000 + 1;
 16         printf("Produce %d\n", queue[p]); 17         sem_post(&product_number);// 能够开释上述操作所占用的资源并唤醒期待执行的下个线程,并且使 semaphore 的 >    值 +1    
 18         p = (p+1)%NUM;// 循环队列 +1
 19         sleep(rand()%5);
 20     }
 21 }
 22 
 23 void *consumer(void *arg)
 24 {
 25     int c = 0;
 26     while (1) {27         sem_wait(&product_number);// 此时 product 线程的 semophore 值曾经从 init 中的 0 变 1, 故此处有 1 个资源可供 wait 应用,不会阻塞!取用后在此变回 0,但能够执行
    后续操作了。28         // 此处因为还有一个信号可供 wait 取用,胜利取用而后持续后续操作
 29         printf("Consume %d\n", queue);
 30         queue = 0;// 取用过的队列值设为 0,便于察看过程间是否同步(即是否 consumer 取了曾经取过的队列值:)31         sem_post(&blank_number);// 开释一个信号(此处开释的是 wait 后续操作所占用的线程信号)给 blank_number 并唤醒下一个阻塞或期待中的过程,semaphore+1
 32         c = (c+1)%NUM;
 33         sleep(rand()%5);
 34     }
 35 }
 36 
 37 int main(int argc, char *argv[])
 38 {
 39     pthread_t pid, cid;
 40 
 41     sem_init(&blank_number, 0, NUM);
 42     sem_init(&product_number, 0, 0);
 43     pthread_create(&pid, NULL, producer, NULL);
 44     pthread_create(&cid, NULL, consumer, NULL);
 45     pthread_join(pid, NULL);
 46     pthread_join(cid, NULL);
 47     sem_destroy(&blank_number);
 48     sem_destroy(&product_number);
 49     return 0;
 50 }

linux 环境下执行:
gcc semaphore.c -o semaphore -lpthread

./semaphore
执行后果如下(FIFO 形式):

正文完
 0