IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux C/C++生产者消费者模型-条件变量-信号量 -> 正文阅读

[系统运维]Linux C/C++生产者消费者模型-条件变量-信号量


一、生产者消费者模型

1.生产者消费者模型是什么

生产者消费者模式 是Controlnet网络中特有的一种传输数据的模式。用于两个CPU之间传输数据,即使是不同类型同一厂家的CPU也可以通过设置来使用。

2.生产者消费者简单代码案例(互斥锁解决)

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.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* s = (struct Node*)malloc(sizeof(struct Node));
        s->next=head;
        head=s;
        s->num=rand()%1000;
        printf("add node,num:%d,tid:%ld\n",s->num,pthread_self());
        pthread_mutex_unlock(&mutex);
        usleep(100);
    }

    return NULL;
}

void* customer(void* arg)
{
    while(1)
    {
        pthread_mutex_lock(&mutex);
        struct Node* p=head;
        if(head!=NULL)
        {
        head=head->next;
        printf("del node,num :%d,tid:%ld\n",p->num,pthread_self());
        free(p);
        pthread_mutex_unlock(&mutex);
        usleep(100);
        continue;
        }
        pthread_mutex_unlock(&mutex);
        
    }

    return NULL;
}


int main()
{
    pthread_mutex_init(&mutex,NULL);

    //创建5个生产者线程
    //创建5个消费者线程
    pthread_t ptid[5];
    pthread_t ctid[5];

    for(int i=0;i<5;i++)
    {
        pthread_create(&ptid[i],NULL,producer,NULL);
        pthread_create(&ctid[i],NULL,customer,NULL);
    }

    for(int i=0;i<5;i++)
    {
        pthread_detach(ptid[i]);
        pthread_detach(ctid[i]);
    }

    while(1)
    {
        sleep(10);
    }

    pthread_mutex_destroy(&mutex);
    pthread_exit(NULL);
    
    
    
}

二、条件变量解决

1.条件变量是什么

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。

2.条件变量常用函数

在这里插入图片描述

3.条件变量解决问题

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.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* s = (struct Node*)malloc(sizeof(struct Node));
        s->next=head;
        head=s;
        s->num=rand()%1000;
        printf("add node,num:%d,tid:%ld\n",s->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* p=head;
        if(head!=NULL)
        {
        head=head->next;
        printf("del node,num :%d,tid:%ld\n",p->num,pthread_self());
        free(p);
        pthread_mutex_unlock(&mutex);
        usleep(100);
        }else{
            //没有数据,需要等待
            //当这个函数调用阻塞的时候,会对互斥锁进行解锁,当不阻塞时,继续加锁
            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 ptid[5];
    pthread_t ctid[5];

    for(int i=0;i<5;i++)
    {
        pthread_create(&ptid[i],NULL,producer,NULL);
        pthread_create(&ctid[i],NULL,customer,NULL);
    }

    for(int i=0;i<5;i++)
    {
        pthread_detach(ptid[i]);
        pthread_detach(ctid[i]);
    }

    while(1)
    {
        sleep(10);
    }


    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    pthread_exit(NULL);
      
    return 0;
}

三、信号量解决

1.信号量是什么

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。

2.信号量函数

在这里插入图片描述

3.信号量解决

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.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* s = (struct Node*)malloc(sizeof(struct Node));
        s->next=head;
        head=s;
        s->num=rand()%1000;
        printf("add node,num:%d,tid:%ld\n",s->num,pthread_self());
        pthread_mutex_unlock(&mutex);
        sem_post(&csem);
    }

    return NULL;
}

void* customer(void* arg)
{
    while(1)
    {
        sem_wait(&csem);
        pthread_mutex_lock(&mutex);
        struct Node* p=head;
        head=head->next;
        printf("del node,num :%d,tid:%ld\n",p->num,pthread_self());
        free(p);
        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 ptid[5];
    pthread_t ctid[5];

    for(int i=0;i<5;i++)
    {
        pthread_create(&ptid[i],NULL,producer,NULL);
        pthread_create(&ctid[i],NULL,customer,NULL);
    }

    for(int i=0;i<5;i++)
    {
        pthread_detach(ptid[i]);
        pthread_detach(ctid[i]);
    }

    while(1)
    {
        sleep(10);
    }


    pthread_mutex_destroy(&mutex);
    pthread_exit(NULL);
      
    return 0;
}

总结

今天主要给大家介绍了生产者消费模型中的一些问题,以及一些具体的解决方案,例如使用条件变量和信号量。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:41:37  更:2022-04-27 11:43:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 20:37:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码