当前位置: 首页 > news >正文

读者、写者问题优化

#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;
}
 

相关文章:

  • 在AMGCL中使用多个GPU和多个计算节点求解大规模稀疏矩阵方程
  • JVM考古现场(十九):量子封神·用鸿蒙编译器重铸天道法则
  • 智能合约安全审计平台——以太坊虚拟机安全沙箱
  • Font Maker的成功之路:产品迭代与创新营销助力增长
  • 国达陶瓷重磅推出陶瓷罗马柱外墙整装尖端新产品“冠岩臻石”
  • Profibus DP主站转modbusTCP网关与dp从站通讯案例
  • 在vue项目中package.json中的scripts 中 dev:“xxx“中的xxx什么概念
  • 爬虫:一文掌握 curl-cffi 的详细使用(支持 TLS/JA3 指纹仿真的 cURL 库)
  • Nacos集群搭建和mysql持久化配置
  • 第三篇:[特殊字符] 深入理解MyBatis[特殊字符] 掌握MyBatis动态SQL——应对复杂查询的有力武器
  • 【vue】轮播图案例
  • 关于python字典的所有操作
  • 性能优化-Spring参数配置、数据库连接参数配置、JVM调优
  • 行锁(Row Locking)和MVCC(多版本并发控制)
  • 空地机器人在复杂动态环境下,如何高效自主导航?
  • ABAP:ME22N控制是否可修改-物料
  • 新晋前端框架技术:小程序容器与SuperApp构建
  • 多模态大语言模型arxiv论文略读(十九)
  • 用 Python 从零构建异步回显服务器
  • OceanBase4.0社区版 单机快速部署
  • 网络社群的早期历史及其启示
  • 寒武纪一季度营收猛增42倍,净利3.55亿元,连续两个季度盈利
  • 擘画开放新篇 共筑合作之桥——中国银行上海市分行全力护航第八届进博会筹备工作
  • 六部门联合印发《促进和规范金融业数据跨境流动合规指南》
  • 用户办“云手机”业务未满月就被终止,广西联通称系商业测试发现技术问题后下架
  • 在这些书里,每一种人生都值得认真过