2

私のコードには、rw_sempaphoremy function への 1 回の呼び出しでロックが解除される がありますunlock()。ただし、私のコードが呼び出されると、現在読み取りロックまたは書き込みロックがあるかどうかがわかりません。up_write()そのため、またはを呼び出す必要があるかどうかはわかりませんup_read()

負の副作用なしに両方を次々に呼び出すことはできますか? 現在のスレッドに読み取りロックまたは書き込みロックがあるかどうかを確認する方法はありますか?

電話をかけてみましdowngrade_write()up_read()が、これも機能していないようです。読み取りロックのダウングレードは悪いことですか?

4

2 に答える 2

1

マイナスの副作用なしに両方を次々に呼び出すことはできますか?

確かに違います!これを想像してみてください:

thread A                    thread B:

down_write
                            down_read (blocked)
...
unlock
|\ up_write
|                           (released, acquired read lock)
| ...
 \ up_read (lock messed up)

私はこれまで使用rw_semaphoreしたことがありませんが、シングルライター-マルチリーダーロックの場合は、これが解決策です。

編集:これには、ロックが再帰的である必要があることに注意してください。それが実際に再帰的ではないrw_semaphoreことが判明した場合。

ロックが読み取りモードまたは書き込みモードのどちらでロックされているかを検出できれば、問題は簡単に解決できます(これらのモードのいずれかでロックされている、つまりロックが解除されていないことがすでにわかっている場合

ロックはマルチリーダーであるため、read-try-lockを使用して状況を知ることができます。

if (down_read_trylock(sem))
    /* semaphore was locked in read mode */
else
    /* semaphore was locked in write mode */

このif場合、セマフォはすでに読み取りモードでロックされており、再度ロックしたため、2 up_read秒必要です。それ以外の場合、セマフォは書き込みモードでロックされているため、1つ必要up_writeです。down_read_trylockこれは、最大数の読み取りロックに到達したこと、またはロックが書き込みモードでロックされていることを除いて、その他の理由で失敗しないことを前提としています。

結論として:

void unlock(struct rw_semaphore *sem)
{
    if (down_read_trylock(sem))
    {
        up_read(sem);
        up_read(sem);
    }
    else
        up_write(sem);
}

注:使用前にテストしてください!

于 2013-03-07T15:03:00.047 に答える