>我在测试线程读写锁时遇到了意外的结果。
以下是我的代码。
#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;
}
跑了几次,偶尔会发现有些意想不到的事情。下面是一个示例:
01 2 3 0
它是读取器线程的输出。基本上,它说数字的大小目前是 5。在这种情况下,我希望结果应该是 0 1 2 3 4。
顺便说一下,我试图实现加法互斥锁,这引发了意外的行为。
我对解决方案和根本原因都很感兴趣。谁能帮我?
任何帮助都将提前表示感谢。
读取器/写入器锁只是防止两个编写器同时运行,或者一个编写器与读取器同时运行。获取输出"0 1 2 3 0"不需要这些东西。因此,您没有理由认为这是意想不到的。
事实上,如果你有四个内核,"0 1 2 3 0"肯定是我至少在某些时候期望的输出。线程按启动顺序运行,直到所有四个内核都使用完毕,然后新线程必须等到现有线程完成其时间片。这在我看来是完全合理的。
如果你能详细说明让你认为"0 1 2 3 0"是出乎意料的思维过程,我们就可以指出其中的具体缺陷。
顺便说一下,对于这样的应用程序,您应该只使用常规锁。仅当读取器操作数明显超过写入操作数或读取器需要保持锁相对较长的时间时,使用读取器/写入器锁才有意义。