Webserver(3.3)生产者消费者模型

news/2024/11/6 11:42:05/

目录

  • 生产者消费者简单模型
  • 条件变量
  • 信号变量

生产者消费者简单模型

//生产者消费者模型#include <stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>struct Node{int num;struct Node * next;
};
//头结点
struct Node * head=NULL;void * producer(void * arg){//不断创建新的节点,添加到链表中while(1){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());usleep(100);}return NULL;
}void * customer(void * arg){while(1){//保存头结点的指针struct Node * tmp=head;head = head->next;printf("del node;num:%d,tid:%ld\n",tmp->num,pthread_self());free(tmp);usleep(100);}return NULL;
}int main(){//创建5个生产者线程,和5个消费者线程pthread_t ptids[5],ctids[5];for(int i=0;i<5;i++){pthread_create(&ptids[i],NULL,producer,NULL);pthread_create(&ctids[5],NULL,customer,NULL);}for(int i=0;i<5;i++){pthread_detach(ptids[i]);pthread_detach(ctids[5]);}// while(1){//     sleep(10);// }pthread_exit(NULL);return 0;
}

在这里插入图片描述
容易出现段错误,原因就是会有几种情况:
会产生数据安全问题,比如生产者还未生产出来,就去消费。

//生产者消费者模型#include <stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>//创建一个互斥
pthread_mutex_t mutex;struct Node{int num;struct Node * next;
};
//头结点
struct Node * head=NULL;void * producer(void * arg){//不断创建新的节点,添加到链表中while(1){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);usleep(100);}return NULL;
}void * customer(void * arg){while(1){//保存头结点的指针pthread_mutex_lock(&mutex);struct Node * tmp=head;//判断是否有数据if(head!=NULL){//有数据head = head->next;printf("del node;num:%d,tid:%ld\n",tmp->num,pthread_self());free(tmp);pthread_mutex_unlock(&mutex);usleep(100);}else{//没有数据pthread_mutex_unlock(&mutex);}}return NULL;
}int main(){pthread_mutex_init(&mutex,NULL);//创建5个生产者线程,和5个消费者线程pthread_t ptids[5],ctids[5];for(int i=0;i<5;i++){pthread_create(&ptids[i],NULL,producer,NULL);pthread_create(&ctids[5],NULL,customer,NULL);}for(int i=0;i<5;i++){pthread_detach(ptids[i]);pthread_detach(ctids[5]);}while(1){sleep(10);}pthread_mutex_destroy(&mutex);pthread_exit(NULL);return 0;
}

解决该问题需要用互斥量确保线程同步,用条件变量或者信号量去解决生产者和消费者之间同步的问题,生产者把数据生产满了要通知消费者去消费。

条件变量

//生产者消费者模型#include <stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>//创建一个互斥
pthread_mutex_t mutex;
//创建条件变量
pthread_cond_t cond;struct Node{int num;struct Node * next;
};
//头结点
struct Node * head=NULL;void * producer(void * arg){//不断创建新的节点,添加到链表中while(1){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_cond_signal(&cond);pthread_mutex_unlock(&mutex);usleep(100);}return NULL;
}void * customer(void * arg){while(1){//保存头结点的指针pthread_mutex_lock(&mutex);struct Node * tmp=head;//判断是否有数据if(head!=NULL){//有数据head = head->next;printf("del node;num:%d,tid:%ld\n",tmp->num,pthread_self());free(tmp);pthread_mutex_unlock(&mutex);usleep(100);}else{//没有数据,需要等待//当wait调用阻塞的时候,会对互斥锁进行解锁,当不阻塞的时候,继续向下执行会重新加锁pthread_cond_wait(&cond,&mutex);pthread_mutex_unlock(&mutex);}}return NULL;
}int main(){pthread_mutex_init(&mutex,NULL);pthread_cond_init(&cond,NULL);//创建5个生产者线程,和5个消费者线程pthread_t ptids[5],ctids[5];for(int i=0;i<5;i++){pthread_create(&ptids[i],NULL,producer,NULL);pthread_create(&ctids[5],NULL,customer,NULL);}for(int i=0;i<5;i++){pthread_detach(ptids[i]);pthread_detach(ctids[5]);}while(1){sleep(10);}pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);pthread_exit(NULL);return 0;
}

在这里插入图片描述

信号变量

//生产者消费者模型#include <stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<semaphore.h>//创建一个互斥
pthread_mutex_t mutex;
//创建两个信号量
sem_t psem;
sem_t csem;struct Node{int num;struct Node * next;
};
//头结点
struct Node * head=NULL;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);usleep(100);}return NULL;
}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);}return NULL;
}int main(){pthread_mutex_init(&mutex,NULL);sem_init(&psem,0,8);sem_init(&csem,0,0);//创建5个生产者线程,和5个消费者线程pthread_t ptids[5],ctids[5];for(int i=0;i<5;i++){pthread_create(&ptids[i],NULL,producer,NULL);pthread_create(&ctids[5],NULL,customer,NULL);}for(int i=0;i<5;i++){pthread_detach(ptids[i]);pthread_detach(ctids[5]);}while(1){sleep(10);}pthread_mutex_destroy(&mutex);pthread_exit(NULL);return 0;
}

在这里插入图片描述


http://www.ppmy.cn/news/1544808.html

相关文章

unreal engine5动画重定向

UE5系列文章目录 文章目录 UE5系列文章目录前言一、下载动画资源二、创建IK Rig&#xff08;IK绑定&#xff09; 前言 在Unreal Engine 5.4中&#xff0c;动画重定向&#xff08;Animation Retargeting&#xff09;和动作匹配&#xff08;Motion Matching&#xff09;是两种不…

PL端:LED闪烁

实验环境 vivado2024.1 实验任务 LED闪烁 引脚关系 硬件配置 新建一个vivado实验 创建 Verilog HDL 文件点亮 LED 点击 Project Manager 下的 Add Sources 图标&#xff08;或者使用快捷键 AltA&#xff09; 编辑led.v module led(input sys_clk,input rst_n,outp…

C语言中如何实现动态内存分配

在C语言中&#xff0c;动态内存分配是通过标准库中的malloc、calloc和free函数实现的。这些函数允许程序在运行时请求内存&#xff0c;从而提供灵活性&#xff0c;尤其是在不知道所需内存大小的情况下。下面是对这三个函数的详细解释和使用示例。 1. malloc malloc&#xff0…

electron 中 ipcRenderer 作用

1. 理解 IPC&#xff08;进程间通信&#xff09;的背景 在 Electron 应用中&#xff0c;有主进程&#xff08;main process&#xff09;和渲染进程&#xff08;renderer process&#xff09;之分。 主进程&#xff1a;负责管理应用程序的生命周期、创建和管理窗口等核心任务。…

【已解决】element-plus配置主题色后,sass兼容问题。set-color-mix-level() is...in Dart Sass 3

项目&#xff1a;vue3vite "scripts": {"dev": "vite","build": "vite build","preview": "vite preview"},"dependencies": {"element-plus/icons-vue": "^2.3.1",&quo…

51单片机教程(八)- 数码管的静态显示

1、项目分析 使用数码管显示指定的字符、数字和符号。 2、技术准备 1、显示器及其接口 单片机系统中常用的显示器有&#xff1a; 发光二极管LED&#xff08;Light Emitting Diode&#xff09;显示器、液晶LCD&#xff08;Liquid Crystal Display&#xff09;显示器、CRT显…

【Vue】在 Vue 组件的 methods 中,箭头函数和不带箭头函数中的this的区别

具体说明 箭头函数在定义时就绑定了它的 this&#xff0c;这个 this 通常是组件定义环境的上下文&#xff08;即创建 Vue 实例之前的环境&#xff09;&#xff0c;而不是 Vue 实例本身。这意味着在 Vue 组件的 methods 中使用箭头函数时&#xff0c;this 通常不会指向 Vue 实例…

TS基础内容(第一部分)

TS基础内容 1.1 TypeScript简介 TypeScript是由微软开发&#xff0c;是基于JavaScript的一个扩展语言TypeScript包含了JavaScript的所有内容&#xff0c;即&#xff1a;TypeScript是JavaScript的超能TypeScript增加了&#xff1a;静态类型检查、接口、泛型等很多现代开发特性…