You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

大学并发课程:C语言读写者问题实现思路咨询

嘿,你这个思路方向完全没问题!咱们把没说完的读线程逻辑补全,再给你一份可运行的C语言实现,帮你把读写者问题落地~

你的思路补全与核心逻辑

你提到的两个锁rd_lock和wr_lock是经典读写者问题(读者优先/公平性可调整)的核心,我帮你把读线程的完整流程补上:

  • 写线程的逻辑可以再优化:其实不需要同时抢占两个锁,只需要wr_lock就够了——因为读线程会在第一个读者到来时锁住wr_lock,直到最后一个读者离开才释放,天然保证了写线程的独占性。
  • 读线程的完整流程:
    1. 先拿rd_lock保护读计数器,避免多个读线程同时修改计数器;
    2. 如果是第一个进入的读线程,就把wr_lock锁住(这样写线程就没法进来了);
    3. 释放rd_lock,安心读取全局变量;
    4. 读完之后,再次拿rd_lock把读计数器减1;
    5. 如果是最后一个离开的读线程,就释放wr_lock(给写线程放行);
    6. 最后释放rd_lock。
完整C语言实现代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

// 全局共享资源
int global_data = 0;
// 两个核心锁
pthread_mutex_t rd_lock;
pthread_mutex_t wr_lock;
// 读计数器,记录当前活跃的读线程数
int read_count = 0;

// 读线程函数
void* reader(void* arg) {
    int thread_id = *(int*)arg;
    while (1) {
        // 第一步:保护读计数器的修改
        pthread_mutex_lock(&rd_lock);
        read_count++;
        // 第一个读线程要锁住写锁,阻止写线程进入
        if (read_count == 1) {
            pthread_mutex_lock(&wr_lock);
        }
        pthread_mutex_unlock(&rd_lock);

        // 读取全局变量(临界区)
        printf("Reader %d: Read global_data = %d\n", thread_id, global_data);
        sleep(1); // 模拟读取耗时

        // 第二步:更新读计数器,释放写锁(如果是最后一个读线程)
        pthread_mutex_lock(&rd_lock);
        read_count--;
        if (read_count == 0) {
            pthread_mutex_unlock(&wr_lock);
        }
        pthread_mutex_unlock(&rd_lock);

        sleep(2); // 模拟读线程的其他工作
    }
    return NULL;
}

// 写线程函数
void* writer(void* arg) {
    int thread_id = *(int*)arg;
    while (1) {
        // 写线程独占写锁,此时所有读、写线程都无法进入临界区
        pthread_mutex_lock(&wr_lock);

        // 修改全局变量(临界区)
        global_data++;
        printf("Writer %d: Updated global_data to %d\n", thread_id, global_data);
        sleep(2); // 模拟写入耗时

        pthread_mutex_unlock(&wr_lock);

        sleep(3); // 模拟写线程的其他工作
    }
    return NULL;
}

int main() {
    pthread_t readers[3], writers[2];
    int ids[5] = {1, 2, 3, 1, 2};

    // 初始化锁
    pthread_mutex_init(&rd_lock, NULL);
    pthread_mutex_init(&wr_lock, NULL);

    // 创建读线程
    for (int i = 0; i < 3; i++) {
        pthread_create(&readers[i], NULL, reader, &ids[i]);
    }
    // 创建写线程
    for (int i = 0; i < 2; i++) {
        pthread_create(&writers[i], NULL, writer, &ids[3+i]);
    }

    // 等待线程结束(这里因为是死循环,实际可以用信号终止)
    for (int i = 0; i < 3; i++) {
        pthread_join(readers[i], NULL);
    }
    for (int i = 0; i < 2; i++) {
        pthread_join(writers[i], NULL);
    }

    // 销毁锁
    pthread_mutex_destroy(&rd_lock);
    pthread_mutex_destroy(&wr_lock);

    return 0;
}
关键细节说明
  • wr_lock的作用:它是写线程的"独占通行证",同时也是读线程的"集体屏障"——只要有读线程在工作,第一个读线程会把它锁住,直到所有读线程都离开才释放,保证写线程不会在读取过程中修改数据。
  • rd_lock的作用:专门保护read_count这个计数器,因为多个读线程可能同时修改它,如果不加锁会出现竞态条件(比如两个读线程同时把read_count从0加到1,导致只锁了一次wr_lock,但实际有两个读线程)。
  • 编译注意事项:编译时需要链接pthread库,命令是:gcc reader_writer.c -o rw -lpthread

内容的提问来源于stack exchange,提问作者resonance

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:52:38