大学并发课程:C语言读写者问题实现思路咨询
嘿,你这个思路方向完全没问题!咱们把没说完的读线程逻辑补全,再给你一份可运行的C语言实现,帮你把读写者问题落地~
你的思路补全与核心逻辑
你提到的两个锁rd_lock和wr_lock是经典读写者问题(读者优先/公平性可调整)的核心,我帮你把读线程的完整流程补上:
- 写线程的逻辑可以再优化:其实不需要同时抢占两个锁,只需要
wr_lock就够了——因为读线程会在第一个读者到来时锁住wr_lock,直到最后一个读者离开才释放,天然保证了写线程的独占性。 - 读线程的完整流程:
- 先拿
rd_lock保护读计数器,避免多个读线程同时修改计数器; - 如果是第一个进入的读线程,就把
wr_lock锁住(这样写线程就没法进来了); - 释放
rd_lock,安心读取全局变量; - 读完之后,再次拿
rd_lock把读计数器减1; - 如果是最后一个离开的读线程,就释放
wr_lock(给写线程放行); - 最后释放
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
相关产品推荐
相关产品推荐

