排他をさらに
考え直してみたら、一度tryrdlock(&rw)とtrylock(&m)に失敗したスレッドではもうtrylock(&m)を試す必要がなかった。つまり
void read() { int rdlockerr = tryrdlock(&rw); if (rdlockerr && trylock(&m)) { rdlockerr = rdlock(&rw); if (rdlockerr) { //エラーなので適当に処理 } } //排他でのread作業 //上のエラーの場合は考慮していない if (rdlockerr) { unlock(&m); } else { unlock(&rw); } }
というコードで充分だ。少しはすっきりしたけどもまだあまり整ってはいない。やはりscoped_lockにした方が良いかなぁ。
-
-
- -
-
pthreadのドキュメントを読み直したらEDEADLKというのがあった。これを使えば良かったらしい。というわけで正しいコードは
rwlock_t rw; void write() { int ret = wrlock(&rw); if (ret) { //エラー処理 } //排他でのwrite作業 unlock(&rw); } void read() { int ret = rdlock(&rw); if (!(!ret || ret==EDEADLK)) { //エラー処理 } //排他でのread作業 if (ret!=EDEADLK) { unlock(&rw); } }
となった(エラー処理も追加)。pthread初心者なのだからドキュメントはちゃんと読まないと。
-
-
- -
-
いや、そうでもなかった。wrlock(&rw)しているスレッドがrdlock(&rw)した場合、必ずしもEDEADLKを返すわけでもないのか。正式な規格を読まないと判らないとしか。ううむ、MT対応に挫折しそうだ。
http://www.opengroup.org/onlinepubs/009695399/
を読めば良いのだろうか。
The pthread_rwlock_rdlock() function may fail if:
[EDEADLK]
A deadlock condition was detected or the current thread already owns the read-write lock for writing.
やはりmayか。