1

スレッドで実行する次のサンプルコード(以下のコードを参照)があります。

A: rd-lock
B: wr-lock (waiting)
A: rd-lock (recursive)
A: rd-unlock (recursive)
A: rd-unlock
B: wr-locked (wake after wait)
B: wr-unlock.

基本的に、読み取りロックは再帰的です。POSIX標準で必要です(読み取りロックは再帰的である必要がありますが、書き込みロックには指定されていません)。これはLinux、FreeBSD、Solarisで機能しますが、Darwin / MacOSXでは機能しません。

以下のサンプルは、Linuxで次の出力を提供します。

read locking
read locked
write locking
read locking 2
read locked 2
read unlocked 2
read unlocked
write locked
write unlocked 2

ダーウィンにいる間、それは印刷します:

read locking
read locked
write locking
read locking 2

そして、ここでのデッドロック(継続しません)、基本的には再帰的な読み取りロックを尊重しません。

期待どおりに機能する可能性のあること(フラグ、定義、特別なライブラリバージョンとのリンク)はありますか?


サンプルコード

#include <pthread.h>
#include <stdio.h>

pthread_rwlock_t lock;

void *thread_r(void *p)
{
    printf("read locking\n");
    pthread_rwlock_rdlock(&lock);
    printf("read locked\n");
    usleep(500*1000);
    printf("read locking 2\n");
    pthread_rwlock_rdlock(&lock);
    printf("read locked 2\n");
    usleep(500*1000);
    pthread_rwlock_unlock(&lock);
    printf("read unlocked 2\n");
    usleep(500*1000);
    pthread_rwlock_unlock(&lock);
    printf("read unlocked\n");
}

void *thread_w(void *p)
{
    usleep(250*1000);
    printf("write locking\n");
    pthread_rwlock_wrlock(&lock);
    printf("write locked\n");
    pthread_rwlock_unlock(&lock);
    printf("write unlocked 2\n");
}

int main()
{
    pthread_t a,b;
    pthread_rwlock_init(&lock,NULL);
    pthread_create(&a,NULL,thread_r,0);
    pthread_create(&b,NULL,thread_w,0);
    pthread_join(a,NULL);
    pthread_join(b,NULL);
    return 0;
}
4

2 に答える 2

1

rdlock() のみが再帰的ロックをサポートします:

http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_rwlock_rdlock.html

Unix 仕様によると、スレッドが既に読み取りロックまたは書き込みロックを保持している場合、wrlock() の呼び出しの動作は未定義です。

http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_rwlock_trywrlock.html

OS X で作業しているので、NSRecursiveLock を見てください。

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html

于 2012-01-10T14:13:39.657 に答える
0

はい、ロックは読み取りロックです。rwlockのロックは、ある時点までは実際に再帰的です。しかし、POSIXドキュメントにpthread_rwlock_rdlockはSUSv2の行があります。これは、Appleがサポートしているものだからです。

ライターがロックを保持しておらず、ロックでブロックされているライターがない場合、呼び出し元のスレッドは読み取りロックを取得します。ライターがロックを保持しておらず、ロックを待機しているライターがいる場合に、呼び出し元のスレッドがロックを取得するかどうかは指定されていません。

既存の読み取りロックを持つスレッドを読み取り用に再ロックさせることについては、何もありません。ライターがブロックされた場合に読み取りロック要求がブロックされるというだけです(実装では、ライターの枯渇を回避するために書き込みロックが優先されることがよくあります)。

Apple独自のオンラインドキュメントもこれをサポートしています。

pthread_rwlock_rdlock()関数は、rwlockが書き込みのために現在保持されておらず、現在ロックでブロックされているライタースレッドがない場合、rwlockの読み取りロックを取得します。

以降:

ライターの飢餓を防ぐために、ライターはリーダーよりも優先されます。

また。書き込みロックがキューにある間、再帰的な読み取りロックを許可することについては言及されていません。

于 2012-01-10T14:18:39.627 に答える