Linux生产者和消费者模型 条件变量 信号量

news2024/11/25 3:00:31

/*
    条件变量类型 pthread_cond_t
    int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
    int pthread_cond_destory(pthread_cond_t * cond);
    int pthread_cond_wait(pthread_cond_t *restrict cond, const pthread_mutex_t *restrict mutex);
        阻塞函数,调用了该函数,线程阻塞
    int pthread_cond_timewait(pthread_cond_t *restrict cond, const pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
        等待多长时间,调用了该函数,线程阻塞直至时间结束
    int pthread_cond_signal(pthread_cond_t * cond);
        唤醒至少一个等待的线程
    int pthread_cond_broadcast(pthread_cond_t * cond);
        唤醒所有等待的线程
*/


#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>

pthread_mutex_t mutex;

pthread_cond_t cond;
struct Node
{
    /* data */
    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, 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 *temp = head;
        if(head != NULL) {
            head = head->next;
            printf("delete node,num:%d, tid:%ld\n", temp->num, pthread_self());
            free(temp);
            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);
    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);
    pthread_cond_destroy(&cond);

    pthread_exit(NULL);

    return 0;
}

/*
    #include <semaphore.h>
    函数量类型:sem_t
    int sem_init(sem_t *sem, int pshared, unsigned int value);
    参数:
        -sem 需要初始化的信号量的地址
        -pshared 表示用在进程还是线程之间 0 线程  非0 进程
        -value:记录信号量中的值

    int sem_destory(sem_t *sem);
        释放资源
    int sem_wait(sem_t *sem);
        对信号量的值减一,如果值为零,就阻塞
    int sem_trywait(sem_t *sem);
    int sem_timewait(sem_t *sem, const struct timespec *abs_timeout);
        等待多久的时间
    int sem_post(sem_t *sem);
        信号量的值加一
    int sem_getvalue(sem_t *sem, int *sval);
*/



#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>
#include <semaphore.h>

pthread_mutex_t mutex;
sem_t psem;
sem_t csem;

struct Node
{
    /* data */
    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, 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 *temp = head;
        head = head->next;
        printf("delete node,num:%d, tid:%ld\n", temp->num, pthread_self());
        free(temp);
        pthread_mutex_unlock(&mutex);

        sem_post(&psem);
        usleep(100);
        
    }
    return 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);

    pthread_exit(NULL);

    return 0;
}

可以把sem理解为车位,wait就占一个车位,pos就空一个车位,车位被占满就阻塞,直至有多余的空出来的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1043158.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人生第一个java项目 学生管理系统

开始编程 建类 开始主要部分 main()部分 方法部分

Nodejs+vue高校机房设备管理系统jt07u

开发语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 集成IDE对高校机房设备管理系统统进行开发,整合系统的各个模块。 拟开发的高校机房设备管理系统通过测试,确保在最大负载的情况下…

新型crypt勒索病毒,都有哪些特征?勒索病毒解密,数据恢复

近日&#xff0c;云天数据恢复中心在接受用户咨询的过程中发现&#xff0c;市场上悄然出现了一种新型的勒索病毒——crypt勒索病毒&#xff0c;接下来我们将这种类型的勒索病毒做一个全面的分析。 一&#xff0c;中了crypt勒索病毒的特征 在桌面以及多个文件夹中都有一个名称为…

matlab产生指定功率的噪声信号、固定SNR的信号

randn函数产生噪声信号 首先要理解信号的幅度和功率&#xff0c;例如信号的幅度为 U U U&#xff0c;那么信号的功率就是 U 2 U^2 U2&#xff0c;他们之间是平方的关系。 matlab中randn函数用法&#xff0c;产生正态分布的随机数或矩阵的函数。 randn&#xff1a;产生均值为0…

基于Java+vue开发的企事业移动培训考试平台

随着移动互联网的快速发展&#xff0c;越来越多的企业开始关注移动培训和考试平台的开发。为了满足这一需求&#xff0c;我们可以使用Java和Vue来开发一个基于移动端的企事业培训考试平台。 一、背景和需求 企事业移动培训考试平台是一个基于Web的应用程序&#xff0c;旨在提…

el-upload上传文件(vue2,Element中的 el-upload文件上传)

简介&#xff1a;el-upload是一个基于Element UI的上传组件&#xff0c;大家应该都知道&#xff0c;它可以方便地实现文件上传功能&#xff0c;今天来记录下如何&#xff08;在vue2中&#xff09;使用el-upload上传文件。 1、首先&#xff0c;我们想要使用el-upload&#xff0c…

Redux Toolkit中action派发但state值不更新的原因

最近一个react项目使用了Redux Toolkit&#xff0c;但是遇到了一个问题&#xff1a;数组始终返回为null&#xff0c;读取不到length. 这个只是问题的表象&#xff0c;真正的原因是productList数据没能从redux中结构出来 但是postman请求是由数据返回的&#xff1a; 推断&#x…

openMVS编译

参考官方文档&#xff1a;https://github.com/cdcseacave/openMVS/wiki/Building vcglib的安装 cd /home/juling/lib git clone -b v1.0.1 https://github.com/cdcseacave/VCG.git vcglibgit clone --recurse-submodules https://github.com/cdcseacave/openMVS.git cd openMV…

git代码管理(一)

目录 介绍暂存区安装创建仓库提交文件查看当前是否还有文件未提交查看提交历史版本回退恢复版本回退 介绍 git是一个分布式的代码版本管理工具&#xff08;区别于集中式管理的svn&#xff09;&#xff0c;分布式的意思是对于同一个项目可以有多个仓库存储&#xff0c;分布在不…

服务器(Windows系统)自建filebrowser网盘服务器超详细教程

需要依赖&#xff08;工具&#xff09; 轻量服务器&#xff08;云服务器&#xff09;一台 —— 环境Windows Server 2019filebrowser安装包&#xff08;https://github.com/filebrowser/filebrowser/releases&#xff09; 下载安装filebrowser 进入链接下载&#xff1a;https:/…

基于OpenSceneGraph的三维模型格式转换(以OBJ为例),并简化、输出纹理图片到指定目录(附完整C++代码和exe)

文章目录 前言一、OpenSceneGraph库1. OSG源码2. 编译教程2. Windows编译完成版 二、osgconv格式转换工具1. osgconv官方说明文档2. osgconv工具调用 三、基于C格式转换&#xff0c;简化OBJ&#xff0c;输出纹理到指定目录1. 项目环境2. 完整代码3. 可执行文件 前言 本文基于O…

记录:移动设备软件开发(Activity的显式启动和隐式启动)

目录 Intent对象简述Intent的作用Intent开启Activtiy显式启动Activity隐式启动Activity Intent对象简述 Android的应用程序包含三种重要组件&#xff1a;Activity、Service、BroadcastReceiver&#xff0c;应用程序采用了一致的方式来启动它们——都是依靠Intent来启动的&…

flv怎么转换成mp4格式?准备3个方法给大家

flv怎么转换成mp4格式&#xff1f;FLV是一种流行的视频文件格式&#xff0c;最初由Adobe公司开发&#xff0c;用于在Web上播放和传输视频内容。FLV格式以其较小的文件大小和较高的压缩比而闻名&#xff0c;并广泛应用于在线视频分享平台、流媒体服务和网络广告等领域。能够提供…

c++图像的边缘检测

图像的边缘检测 cv::Canny 是 OpenCV 中用于进行边缘检测的函数&#xff0c;特别是用于检测图像中的边缘。Canny 边缘检测是一种广泛使用的技术&#xff0c;它能够识别图像中的边缘&#xff0c;这些边缘通常表示对象之间的边界或图像中的显著特征 void cv::Canny(const cv::M…

linux 查看CPU架构是AMD还是ARM

要查看 Linux 系统的 CPU 架构是 AMD 还是 ARM&#xff0c;可以使用以下命令&#xff1a; 使用 lscpu 命令并查找 Architecture 字段&#xff1a; lscpu | grep Architecture如果输出结果中包含 x86_64 或 i686&#xff0c;则表示系统的 CPU 架构是 AMD&#xff08;或者是 x86…

地球红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——世界旅行季许少辉八月新书辉少许

地球红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——世界旅行季许少辉八月新书辉少许 地球红薯地中秋圆《乡村振兴战略下传统村落文化旅游设计》——世界旅行季许少辉八月新书辉少许

Python中的用法与常见问题解析

装饰器是Python语言中一种强大且常用的概念。通过装饰器&#xff0c;我们可以在不修改原始函数代码的情况下&#xff0c;给函数添加额外的功能&#xff0c;比如日志记录、性能分析、输入验证等。在本文中&#xff0c;我们将深入探讨Python中装饰器的用法和常见问题&#xff0c;…

接口自动化测试:pytest基础讲解

为什么要做接⼝测试&#xff1f; 只靠前端测试很难确保很⾼的覆盖率。接⼝测试&#xff0c;可以模拟出各种类型的⼊参&#xff0c;包括⼀些在前端模拟不出来的⼊参&#xff0c;还能根据接⼝⽂档的定义&#xff0c;设计出相对完善的⼊参值&#xff0c;在接⼝层保证质量&#xff…

@PostMapping‘ not applicable to type 这个是什么原因

PostMapping’ not applicable to type 这个是什么原因 这个错误的意思是 ‘PostMapping’ 注解没有被正确地应用到一个合适的元素上。在Spring MVC中&#xff0c;PostMapping通常用于注解一个处理HTTP POST请求的方法。 出现这个错误&#xff0c;可能的原因有&#xff1a; …

【STM32】读写内部Flash初步使用

基于stm32f103&#xff0c;作为个人学习记录使用 STM32 芯片内部有一个 FLASH 存储器&#xff0c;它主要用于存储代码,在紧急状态下常常会使用内部 FLASH 存储关键记录&#xff1b; 内部 FLASH 的构成 STM32 的内部 FLASH 包含主存储器、系统存储器以及选项字节区域 大容量…