0

我在测试 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。

顺便说一句,我试图实现加法互斥锁,这会引发意想不到的行为。

我对解决方案和根本原因都很感兴趣。谁能帮帮我?

提前感谢任何帮助。

4

1 回答 1

0

读取器/写入器锁只是防止两个写入器同时运行或一个写入器作为读取器同时运行。获得输出“0 1 2 3 0”不需要这些东西。因此,您没有理由认为这是出乎意料的。

事实上,如果你有四个核心,“0 1 2 3 0”肯定是我至少在某些时候期望的输出。线程按照它们启动的顺序运行,直到所有四个内核都在使用中,然后新线程必须等到现有线程完成它们的时间片。这对我来说似乎完全合理。

如果您能详细说明让您认为“0 1 2 3 0”出乎意料的思维过程,我们可以指出其中的具体缺陷。

顺便说一句,对于这样的应用程序,您应该只使用常规锁。仅当读取器操作明显多于写入操作或读取器需要持有锁相对较长时间时,使用读取器/写入器锁才有意义。

于 2016-01-14T19:06:18.863 回答