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

リーダー/ライター ロックは、2 つのライターが同時に実行されること、またはライターがリーダーと同時に実行されることを防止するだけです。出力「0 1 2 3 0」を取得するために、これらのいずれも必要ありません。したがって、それを予期しないと考える理由はありません。

実際、コアが 4 つある場合、「0 1 2 3 0」は確かに、少なくとも時々期待される出力です。スレッドは、4 つのコアすべてが使用されるまで、開始された順序で実行されます。新しいスレッドは、既存のスレッドがタイムスライスを終了するまで待機する必要があります。それは私には完全に理にかなっているように思えます。

「0 1 2 3 0」が予想外であると考えさせられた思考プロセスを詳しく説明できれば、その特定の欠陥を指摘できます。

ちなみに、このようなアプリケーションでは、通常のロックを使用する必要があります。リーダー/ライター ロックの使用は、リーダー操作が書き込み操作よりも大幅に多い場合、またはリーダーが比較的長時間ロックを保持する必要がある場合にのみ意味があります。

于 2016-01-14T19:06:18.863 に答える