读者、写者问题优化

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

#define NUM_READERS 5
#define NUM_WRITERS 5

// 定义信号量和全局变量
sem_t sdata, srcount;
int readcount = 0;

// 建议在每个线程中使用局部随机数生成,不重复调用srand()(可在主线程调用一次)
 
void* reader(void* p) {
    int id = *(int*)p + 1;
    // 为每个线程设置一个线程局部种子,使用线程ID与时间混合生成
    unsigned int seed = time(NULL) ^ id;
    while (1) {
        int sleepTime = rand_r(&seed) % 5 + 1; // 随机[1,5]秒

        // 进入读者协议
        sem_wait(&srcount);
        readcount++;
        if (readcount == 1) { // 第一个读者锁定共享资源
            sem_wait(&sdata);
        }
        sem_post(&srcount);

        // 模拟读操作
        printf("读者 %d 开始读取...\n", id);
        sleep(sleepTime);
        printf("读者 %d 读取完成,耗时 %d 秒\n", id, sleepTime);

        // 离开读者协议
        sem_wait(&srcount);
        readcount--;
        if (readcount == 0) { // 最后一个读者释放共享资源
            sem_post(&sdata);
        }
        sem_post(&srcount);

        sleep(1); // 读者操作后稍作延时,再尝试下一次读取
    }
    return NULL;
}

void* writer(void* p) {
    int id = *(int*)p + 1;
    unsigned int seed = time(NULL) ^ id;
    while (1) {
        int sleepTime = rand_r(&seed) % 5 + 1; // 随机写入时间

        // 写者请求进入共享资源
        sem_wait(&sdata);
        printf("写者 %d 开始写入...\n", id);
        sleep(sleepTime);
        printf("写者 %d 写入完成,耗时 %d 秒\n", id, sleepTime);
        sem_post(&sdata);

        sleep(1); // 写者操作后延时
    }
    return NULL;
}

int main(void) {
    int i;
    // 初始化信号量
    sem_init(&sdata, 0, 1);
    sem_init(&srcount, 0, 1);

    pthread_t readers[NUM_READERS], writers[NUM_WRITERS];
    int thread_ids[NUM_READERS > NUM_WRITERS ? NUM_READERS : NUM_WRITERS];
    
    // 初始化随机种子只需一次(如果需要全局 seed 可在此设定)
    srand(time(NULL));

    // 创建读者线程
    for (i = 0; i < NUM_READERS; i++) {
        thread_ids[i] = i;
        pthread_create(&readers[i], NULL, reader, &thread_ids[i]);
    }
    // 创建写者线程
    for (i = 0; i < NUM_WRITERS; i++) {
        thread_ids[i] = i;
        pthread_create(&writers[i], NULL, writer, &thread_ids[i]);
    }

    // 等待所有线程结束(实际上本示例为无限循环,可使用其他退出条件)
    for (i = 0; i < NUM_READERS; i++) {
        pthread_join(readers[i], NULL);
    }
    for (i = 0; i < NUM_WRITERS; i++) {
        pthread_join(writers[i], NULL);
    }
    
    sem_destroy(&sdata);
    sem_destroy(&srcount);
    return 0;
}
 

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

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

相关文章

如何通过前端表格控件实现自动化报表?1

背景 最近伙伴客户的项目经理遇见一个问题&#xff0c;他们在给甲方做自动化报表工具&#xff0c;项目已经基本做好了&#xff0c;但拿给最终甲方&#xff0c;业务人员不太买账&#xff0c;项目经理为此也是天天抓狂&#xff0c;没有想到合适的应对方案。 现阶段主要面临的问…

RabbitMQ 优先级队列详解

本文是博主在记录使用 RabbitMQ 在执行业务时遇到的问题和解决办法&#xff0c;因此查阅了相关资料并做了以下记载&#xff0c;记录了优先级队列的机制和使用要点。 本文为长文&#xff0c;详细介绍了相关的知识&#xff0c;可作为学习资料看。 文章目录 一、优先级队列介绍1、…

代理模式简述

目录 一、主要角色 二、类型划分 三、静态代理 示例 缺点 四、动态代理 JDK动态代理 示例 缺点 CGLib动态代理 导入依赖 示例 五、Spring AOP 代理模式是一种结构型设计模式&#xff0c;通过代理对象控制对目标对象的访问&#xff0c;可在不改变目标对象情况下增强…

每日一题——云服务计费问题

云服务计费问题&#xff08;哈希表 排序&#xff09;| 附详细 C源码解析 一、题目描述二、输入描述三、输出描述四、样例输入输出输入示例&#xff1a;输出示例&#xff1a;说明&#xff1a; 五、解题思路分析六、C实现源码详解&#xff08;完整&#xff09;七、复杂度分析 一…

【JVM】运行时数据区域

文章目录 1. 程序计数器补充 2. 虚拟机栈2.1 栈帧1. 局部变量表2. 操作数栈3. 动态链接4. 方法返回地址补充 3. 本地方法栈4. 堆5. 方法区静态常量池&#xff08;Class常量池&#xff09;运行时常量池字符串常量池&#xff08;1&#xff09;位置变化&#xff08;2&#xff09;放…

day28图像处理OpenCV

文章目录 一、图像预处理4 边缘填充4.1 边界复制&#xff08;BORDER_REPLICATE&#xff09;4.2 边界反射&#xff08;BORDER_REFLECT&#xff09;4.3 边界反射101&#xff08;BORDER_REFLECT_101&#xff09;4.4 边界常数&#xff08;BORDER_CONSTANT&#xff09;4.5 边界包裹&…

C++ Json-Rpc框架-3项目实现(2)

一.消息分发Dispatcher实现 Dispatcher 就是“消息分发中枢”&#xff1a;根据消息类型 MType&#xff0c;把消息派发给对应的处理函数&#xff08;Handler&#xff09;执行。 初版&#xff1a; #pragma once #include "net.hpp" #include "message.hpp"n…

C++算法优化实战:破解性能瓶颈,提升程序效率

C算法优化实战&#xff1a;破解性能瓶颈&#xff0c;提升程序效率 在现代软件开发中&#xff0c;算法优化是提升程序性能的关键手段之一。无论是在高频交易系统、实时游戏引擎&#xff0c;还是大数据处理平台&#xff0c;算法的高效性直接关系到整体系统的性能与响应速度。C作…

【PostgreSQL教程】PostgreSQL 特别篇之 语言接口连接PHP

博主介绍:✌全网粉丝22W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…

山东大学软件学院创新项目实训开发日志(12)之将对话记录保存到数据库中

在之前的功能开发中&#xff0c;已经成功将deepseekAPI接口接入到springbootvue项目中&#xff0c;所以下一步的操作是将对话和消息记录保存到数据库中 在之前的开发日志中提到数据库建表&#xff0c;所以在此刻需要用到两个表&#xff0c;conversation表和message表&#xff…

Spring-注解编程

注解基础概念 1.什么是注解编程 指的是在类或者方法上加入特定的注解(XXX) 完成特定功能的开发 Component public classXXX{} 2.为什么要讲注解编程 1.注解开发方便 代码简洁 开发速度大大提高 2.Spring开发潮流 Spring2.x引入注解 Spring3.x完善注解 Springboot普及 推广注解…

Dify智能体平台源码二次开发笔记(5) - 多租户的SAAS版实现(2)

目录 前言 用户的查询 controller层 添加路由 service层 用户的添加 controller层 添加路由 service层-添加用户 service层-添加用户和租户关系 验证结果 结果 前言 完成租户添加功能后&#xff0c;下一步需要实现租户下的用户管理。基础功能包括&#xff1a;查询租…

基于若依的ruoyi-vue-plus的nbmade-boot在线表单的设计(一)架构方面的设计

希望大家一起能参与我的新开源项目nbmade-boot: 宁波智能制造低代码实训平台 主要目标是类似设计jeecgboot那样的online表单功能,因为online本身没有开源这部分代码,而我设计这个是完全开源的,所以希望大家支持支持,开源不容易。 1、数据库方面设计考虑 是在原来gen_table和…

WebFlux应用中获取x-www-form-urlencoded数据的六种方法

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

[Python基础速成]1-Python规范与核心语法

本系列旨在快速掌握Python&#xff0c;实现能够快速阅读和理解 Python 代码&#xff0c;并在可查阅语法的情况下进行 AI 学习。 本篇先了解一下Python基础知识。 本篇内容较菜鸟教程有所删减、方便快速构建大纲&#xff0c;且加入了PEP 8规范说明等有助于理解和编写代码的说明。…

农民剧团的春天与改变之路

杨天义&#xff0c;男&#xff0c;1966年9月生&#xff0c;中共党员&#xff0c;江西省吉安市吉水县水南农民剧团团长。 杨天义从废品收购起家&#xff0c;凭借自身的努力和奋斗&#xff0c;自筹资金100余万元建设了水南镇的第一座影剧院&#xff0c;组建了江西省吉安市吉水县…

python asyncio 的基本使用

1、引言 asyncio 是 Python 标准库中的一个库&#xff0c;提供了对异步 I/O 、事件循环、协程和任务等异步编程模型的支持。 asyncio 文档 2、进程、线程、协程 线程 线程是操作系统调度的基本单位&#xff0c;同一个进程中的多个线程共享相同的内存空间。线程之间的切换由操…

Leedcode刷题 | Day30_贪心算法04

一、学习任务 452. 用最少数量的箭引爆气球代码随想录435. 无重叠区间763. 划分字母区间 二、具体题目 1.452用最少数量的箭引爆气球452. 用最少数量的箭引爆气球 - 力扣&#xff08;LeetCode&#xff09; 在二维空间中有许多球形的气球。对于每个气球&#xff0c;提供的输…

Ant Design Vue 表格复杂数据合并单元格

Ant Design Vue 表格复杂数据合并单元格 官方合并效果 官方示例 表头只支持列合并&#xff0c;使用 column 里的 colSpan 进行设置。 表格支持行/列合并&#xff0c;使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时&#xff0c;设置的表格不会渲染。 <temp…

C++ 标准库中的 <algorithm> 头文件算法总结

C 常用 <algorithm> 算法概览 C 标准库中的 <algorithm> 头文件提供了大量有用的算法&#xff0c;主要用于操作容器&#xff08;如 vector, list, array 等&#xff09;。这些算法通常通过迭代器来操作容器元素。 1. 非修改序列操作 std::all_of, std::any_of, s…