创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
c语言内容💖:
专栏:c语言之路重点知识整合
【c语言】全部知识点总结
目录
- 信号量
- 分析
- 代码
- 运行结果
信号量
信号量是一种同步机制,可用于保护共享资源,控制进程的访问以及协调进程之间的通信。
在生产者和消费者问题中,可以使用两个信号量:一个用于生产者,另一个用于消费者。
假设缓冲区的大小为N,生产者信号量的初始值为N,消费者信号量的初始值为0。
接下来,生产者和消费者可以使用P操作和V操作来访问缓冲区。
P操作(等待信号量):如果信号量的值为0,则进程将阻塞,直到信号量的值变为正数。如果信号量的值大于0,则进程将减少信号量的计数器并继续执行。
V操作(释放信号量):如果有进程在等待信号量,则唤醒其中一个进程。否则,信号量的计数器将增加,以表示一个资源已经可用。
分析
创建两个线程,一个用于生产者,另一个用于消费者。它们共享一个大小为5的环形缓冲区。
当生产者线程生成一个新项目时,它使用blank_number信号量将空闲空间的数量减少1,然后使用互斥变量mutex1添加到环形缓冲区中。生产者使用product_number信号量将队列项目的数量增加1。
当消费者线程消费一个项目时,它使用product_number信号量将队列项目的数量减少1,然后使用互斥变量mutex1从环形缓冲区中删除。消费者使用blank_number信号量将空余的空间数量增加1。
这种基于信号量的方法可以保证生产者和消费者之间的同步性。
-
如果缓存区已满,则生产者线程将在blank_number信号量处阻塞,并等待直至有可用的空间。
-
如果缓存区为空,则消费者线程将在product_number信号量处阻塞。
代码
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#define NUM 5
int queue[NUM]; //全局数组实现环形队列
sem_t blank_number, product_number, mutex1; //空格子信号量, 产品信号量
void *producer(void *arg)
{
int i = 0;
while (1) {
sem_wait(&blank_number); //生产者将空格子数--,为0则阻塞等待
sem_wait(&mutex1);
queue[i] = rand() % 1000 + 1; //生产一个产品
printf("----Produce---%d\n", queue[i]);
sem_post(&mutex1);
sem_post(&product_number); //将产品数++
i = (i+1) % NUM; //借助下标实现环形
sleep(rand()%3);
}
}
void *consumer(void *arg)
{
int i = 0;
while (1) {
sem_wait(&product_number); //消费者将产品数--,为0则阻塞等待
sem_wait(&mutex1);
printf("-Consume---%d\n", queue[i]);
queue[i] = 0; //消费一个产品
sem_post(&mutex1);
sem_post(&blank_number); //消费掉以后,将空格子数++
i = (i+1) % NUM;
sleep(rand()%3);
}
}
int main(int argc, char *argv[])
{
pthread_t pid, cid;
sem_init(&blank_number, 0, NUM); //初始化空格子信号量为5
sem_init(&product_number, 0, 0); //产品数为0
sem_init(&mutex1, 0, 1);
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
sem_destroy(&blank_number);
sem_destroy(&product_number);
return 0;
}
运行结果
大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。 |
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●) |