1

C でリーダー/ライター ロックを実装しました。リーダーの数を制限したいので、「num」を使用してカウントします。この実装に潜在的なデータ競合またはデッドロック状態があるかどうかはわかりません。それで、それらを理解するのを手伝ってくれませんか?

別の質問は、何らかの方法で struct _rwlock の「spin_lock」を削除できますか? ありがとう!

#define MAX_READER 16; 
typedef _rwlock *rwlock;
struct _rwlock{
    spin_lock   lk;
    unint32_t   num;
};
void wr_lock(rwlock lock){
    while (1){
        if (lock->num > 0) continue;
        lock(lock->lk);
        lock->num += MAX_READER;
        return;
    }
}
void wr_unlock(rwlock lock){
    lock->num -= MAX_READER;
    unlock(lock->lk);
}
void rd_lock(rwlock lock){
    while (1){
        if (lock->num >= MAX_READER) continue;
        atom_inc(num);
        return;
    }
}
void rd_unlock(rwlock lock){
    atom_dec(num);
}
4

2 に答える 2

2

簡単な回答: はい、ここには重大な問題があります。使用している同期ライブラリはわかりませんが、共有データへのアクセスを保護しておらず、rd_lock() と wr_lock() のループで大量の CPU サイクルを浪費します。事実上すべてのケースで、スピン ロックを避ける必要があります (ただし、例外もあります)。

于 2012-10-07T19:11:42.720 に答える
2

wr_lock(および で同様rd_lock):

while (1){
    if (lock->num > 0) continue;

これは間違っています。何らかの方法で同期しないと、他のスレッドからの変更が表示される保証はありません。これが唯一の問題である場合は、おそらくロックを取得してからカウントを確認できます。

rd_lock

atom_inc(num);

これは、非アトミック関数やライター関数ではうまく機能しません+=-=それらを中断する可能性があるためです。の減分についても同じですrd_unlock

rd_lockスレッドがライターとしてロックを保持している間に戻ることができます-これは、リーダー/ライター ロックの通常のセマンティクスではありません。つまり、rw-lock が保護するはずのものは何でも保護しないことを意味します。

pthreads を使用している場合は、すでに rwlock があります。Windows では、SRWlocks を検討してください (自分で使用したことはありません)。移植可能なコードの場合は、条件変数を使用して rwlock を作成します (または、リーダー用とライター用の 2 つ)。つまり、C のマルチスレッド コードが移植可能である限りはそうです。C11 には条件変数があり、C11 より前のスレッドの実装が存在しない場合、それを使用する必要はありません ;-)

于 2012-10-07T19:35:30.447 に答える