我在测试pthread读写锁时遇到了意外的结果。
以下是我的代码。
#include <iostream>
#include <thread>
#include <pthread.h>
//locks declaration
pthread_rwlock_t rwlock;
//shared resource
int numbers[20];
int size = 0;
void readFrom()
{
int rc;
rc = pthread_rwlock_rdlock(&rwlock);
for(int index = 0; index < size; index++) {
std::cout << numbers[index] << " ";
}
std::cout << std::endl;
rc = pthread_rwlock_unlock(&rwlock);
}
void writeTo(int index, int val)
{
int rc;
rc = pthread_rwlock_wrlock(&rwlock);
numbers[index] = val;
size++;
rc = pthread_rwlock_unlock(&rwlock);
}
int main(int argc, char **argv)
{
int rc=0;
std::cout << std::endl;
std::thread threads[25];
rc = pthread_rwlock_init(&rwlock, NULL);
for(int i=0; i<20; ++i) {
threads[i] = std::thread(writeTo, i, i);
if(i % 5 == 0) {
threads[20 + (i / 5)] = std::thread(readFrom);
}
}
for(int i=0; i<24; ++i) {
threads[i].join();
}
std::cout << "size is " << size << std::endl;
threads[24] = std::thread(readFrom);
threads[24].join();
std::cout << std::endl;
rc = pthread_rwlock_destroy(&rwlock);
return 0;
}
几次运行后,我偶尔发现有一些意想不到的事情。这是一个例子:
0 1 2 3 0
它是读者线程的输出。基本上,它说数字的大小现在是5。在这种情况下,我希望结果应为0 1 2 3 4.
顺便说一下,我试图实现添加互斥锁,这会引发意外行为。
我对解决方案以及根本原因感兴趣。谁能帮助我?
提前感谢任何帮助。
答案 0 :(得分:0)
读取器/写入器锁定只是防止两个写入器同时运行或者写入器与读取器同时运行。这些东西都不需要输出&#34; 0 1 2 3 0&#34;。所以你没有理由认为这是出乎意料的。
事实上,如果你有四个核心,&#34; 0 1 2 3 0&#34;肯定是我至少在某些时候所期望的输出。线程按照它们启动的顺序运行,直到所有四个核都在使用,然后新线程必须等到现有线程完成其时间片。这对我来说似乎完全合情合理。
如果你能详细说明让你思考的思考过程&#34; 0 1 2 3 0&#34;出乎意料的是,我们可以指出其中的具体缺陷。
顺便说一下,对于像这样的应用程序,你应该只使用常规锁。当读取器操作明显超过写入操作或读取器需要长时间保持锁定时,使用读取器/写入器锁定才有意义。