当前位置:网站首页>信号量解决生产者消费者问题
信号量解决生产者消费者问题
2022-07-30 05:39:00 【l_ethan】
生产者消费者问题:生产者不能在容器满了继续生成,消费者不能在容器为空的时候消费
1.信号量简介
用户进程可以通过操作系统提供的一对原语来对信号量进行操作,从而很方便的实现了进程互斥、进程同步。信号量是一个变量来表示系统中某种资源的数量。
原语:是一种特殊的程序段,其执行只能一气呵成,不可被中断。
p、v操作
p:
1.s-1
2. s-1>=0进程继续执行
3.s-1<0,进程阻塞进入等待队列,转进程调度
v
1.s+1
2.s+1>0进程继续执行
3.s+1<=0,则从该信号的等待队列中唤醒一等待进程,然后在返回原进程继续执行或转进程调度
2.信号量函数原型
sem_init
int sem_init(sem_t *sem, int pshared, unsigned int value);-功能:初始化信号量
-参数:
-sem:信号量变量的地址
-pshared:0用在线程间,非0用在进程间
-value:信号量中的值
sem_destroy
int sem_destroy(sem_t *sem);-功能:释放资源
sem_wait
int sem_wait(sem_t *sem);-功能:对信号量加锁,调用一次对信号量的值-1,如果值为0,就阻塞
sem_trywait/sem_timedwait
int sem_trywait(sem_t *sem);
-功能:尝试对信号量加锁,调用一次对信号量的值-1,如果值为0,不阻塞
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
-功能:尝试对信号量加锁,调用一次对信号量的值-1,如果值为0,等待设置的时间sem_post
int sem_post(sem_t *sem);功能:对信号量解锁,调用一次对信号量的值+1
3.案例源码
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
//创建一个互斥量
pthread_mutex_t mutex;
//创建两个信号量
sem_t psem;
sem_t csem;
struct Node{
int num;
struct Node *next;
};
struct Node *head;
void *producer(void *arg){
//创建新的节点,添加到链表中
while(1){
sem_wait(&psem);
pthread_mutex_lock(&mutex);
struct Node * newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->next=head;
head=newNode;
newNode->num=rand()%1000;
printf("add node, num %d,tid :%ld\n",newNode->num,pthread_self());
pthread_mutex_unlock(&mutex);
sem_post(&csem);
}
}
void *customer(void *arg){
while(1){
sem_wait(&csem);
pthread_mutex_lock(&mutex);
struct Node *tmp=head;
head=head->next;
printf("del node, num:%d,tid:%ld\n",tmp->num,pthread_self());
free(tmp);
pthread_mutex_unlock(&mutex);
sem_post(&psem);
}
}
//头节点
struct Node * head = NULL;
int main(){
pthread_mutex_init(&mutex,NULL);
sem_init(&psem,0,8);
sem_init(&csem,0,0);
//创建五个生产者线程和五个消费者线程
pthread_t ptids[5],ctids[5];
for(int i=0;i<5;i++){
pthread_create(&ptids[i],NULL,producer,NULL);
pthread_create(&ctids[i],NULL,customer,NULL);
}
for(int i=0;i<5;i++){
pthread_detach(ptids[i]);
pthread_detach(ctids[i]);
}
while(1){
sleep(10);
}
pthread_mutex_destroy(&mutex);
sem_destroy(&psem);
sem_destroy(&csem);
pthread_exit(NULL);
return 0;
}边栏推荐
猜你喜欢

Frobenius norm(Frobenius 范数)

cmd (command line) to operate or connect to the mysql database, and to create databases and tables

Error: npm ERR code EPERM

This dependency was not found:

2022年SQL大厂高频实战面试题(详细解析)

MySql fuzzy query Daquan

瑞吉外卖项目:新增菜品与菜品分页查询

Teach you to completely uninstall MySQL
![[详解C语言]一文带你玩转数组](/img/1b/245fdc7f3711cf794175da7a93b128.png)
[详解C语言]一文带你玩转数组

What is SOA (Service Oriented Architecture)?
随机推荐
每日练习------输出一个整数的二进制数、八进制数、十六进制数。
Basic syntax of MySQL DDL and DML and DQL
MySQL database basics (a systematic introduction)
留念 · 大学时代最后的系统设计图
“tensorflow.keras.preprocessing“ has no attribute “image_dataset_from_directory“
ezTrack-master使用教程
Ranking of grades (Huazhong University of Science and Technology postgraduate examination questions) (DAY 87)
报错:npm ERR code EPERM
Different usage scenarios of subqueries as retrieval tables and the question of whether to add aliases
pytorch中的线性代数
手把手教你设计一个CSDN系统
个人博客系统(附源码)
51.N皇后(回溯法)
871.最低加油次数(动态规划)
[GO语言基础] 一.为什么我要学习Golang以及GO语言入门普及
[GO Language Basics] 1. Why do I want to learn Golang and the popularization of GO language entry
[GStreamer] The name of the plugin should match GST_PLUGIN_DEFINE
MySQL模糊查询性能优化
934.最短的桥(广度优先搜索)
SRA数据下载方法总结