c++模拟读者写者问题
时间: 2023-08-03 22:10:32 浏览: 52
读者写者问题是一个经典的同步问题,其中多个读者和写者进程共享同一个共享资源,例如数据库。读者仅仅是读取共享资源的值,而写者则是修改共享资源的值。在读者和写者之间必须进行正确的同步,以保证共享资源的正确性。
下面是使用C++编写的一种解决方案,其中使用了互斥锁和条件变量来实现同步:
```c++
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
mutex mtx; // 互斥锁
condition_variable cv_read, cv_write; // 读写条件变量
int read_cnt = 0, write_cnt = 0; // 读写计数器
bool writing = false; // 写标志
void reader(int id) {
while (true) {
unique_lock<mutex> lock(mtx);
while (write_cnt > 0 || writing) cv_read.wait(lock); // 等待写者完成
read_cnt++;
cout << "Reader " << id << " reads data" << endl;
if (--read_cnt == 0) cv_write.notify_one(); // 唤醒等待的写者
lock.unlock();
this_thread::sleep_for(chrono::milliseconds(1000)); // 模拟读操作
}
}
void writer(int id) {
while (true) {
unique_lock<mutex> lock(mtx);
while (read_cnt > 0 || writing) cv_write.wait(lock); // 等待读者完成
writing = true;
write_cnt++;
cout << "Writer " << id << " writes data" << endl;
writing = false;
if (--write_cnt == 0) cv_read.notify_all(); // 唤醒等待的读者
lock.unlock();
this_thread::sleep_for(chrono::milliseconds(2000)); // 模拟写操作
}
}
int main() {
thread r1(reader, 1), r2(reader, 2), w1(writer, 1), w2(writer, 2);
r1.join();
r2.join();
w1.join();
w2.join();
return 0;
}
```
在上面的代码中,读者线程和写者线程都被定义为无限循环,并且使用条件变量进行同步。当读者线程需要访问共享资源时,会先获得互斥锁,然后判断是否有写者正在访问共享资源,如果有,则等待条件变量进行唤醒;如果没有,则增加读计数器,然后释放互斥锁。当读者线程完成访问共享资源时,会再次获得互斥锁,然后减少读计数器,然后判断是否需要唤醒等待的写者线程。
当写者线程需要访问共享资源时,会先获得互斥锁,然后判断是否有读者或写者正在访问共享资源,如果有,则等待条件变量进行唤醒;如果没有,则设置写标志,并增加写计数器,然后释放互斥锁。当写者线程完成访问共享资源时,会再次获得互斥锁,然后减少写计数器,并清除写标志,然后判断是否需要唤醒等待的读者线程。
最后,在主函数中启动四个线程,两个读者线程和两个写者线程,然后等待线程结束,程序结束。
相关推荐
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)