- PR -

pthread_mutex_lockによる長時間のロック

1
投稿者投稿内容
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2008-06-30 20:11
いつもお世話になっております。
pthreadについての質問です。プラットフォームはPOSIX全般を想定しています。

Web上の解説で、「mutexは短時間のロックに用いるべきで、ロックの時間が長くなるなら、セマフォや条件変数を使うべき」という記述をみかけたことがあります。

おそらく、プログラムとしては、
・mutex版疑似コード(mutexによる排他制御)
コード:
pthread_mutex_lock();
クリティカルセクション
pthread_mutex_unlock();


・条件変数版疑似コード(フラグによる排他制御、mutexはフラグの保護に用いる)
コード:
pthread_mutex_lock();
while ( フラグ )
  pthread_cond_wait();
フラグ=true;
pthread_mutex_unlock();
クリティカルセクション
pthread_mutex_lock();
フラグ=false;
pthread_cond_signal(); ( または pthread_cond_broadcast() )
pthread_mutex_unlock();


のような感じになると考えています。( pthreadの関数で代替を考え、セマフォではなく条件変数を使いました )

ここで、クリティカルセクションの処理時間が長くなる時、どちらのコードであっても、スレッドが待ち続ける状況は変わらないと思うのですが、それでもやはり前者の方式は良くないのでしょうか。どなたか理由をご存知でしたら、ご教示ください。

なお、スレッドのキャンセル ( pthread_cancel ) は使わないことを想定しているため、pthread_mutex_lock がキャンセルポイントにならない ( 長時間のロック待ちでキャンセル遅延が発生する ) ことは気にしていません。

以上、よろしくお願いします。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2008-07-01 00:30
引用:

angelさんの書き込み (2008-06-30 20:11) より:
なお、スレッドのキャンセル ( pthread_cancel ) は使わないことを想定しているため、pthread_mutex_lock がキャンセルポイントにならない ( 長時間のロック待ちでキャンセル遅延が発生する ) ことは気にしていません。



その辺じゃないですか?キャンセルポイントにも近いところですが、
sem_wait(3)やpthread_cond_timedwait(3)はEINTRを返せたりもします。

条件変数を応用したロックであれば、
Two-Phase Terminationをロックの待機に組み込むこともできます。

中断する方法を残しておけ、ということではないでしょうか。
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2008-07-04 18:10
あしゅさん、ありがとうございます。

そうすると、スレッドのキャンセルが絡む時の事を考えて、mutex での長時間のロックはしない、ということになるのでしょうか。
Two-Phase Termination のお話が出る、ということは、やはりスレッドのキャンセルが行われる、という前提なのでしょうし。
※今回に限ってはキャンセルを考えないので、同じになりそうな気がしますが

ちょっと分からなかったのが、EINTR の話と、「条件変数を応用したロックであれば、Two-Phase Terminationを組み込むことができる」という下りです。

まず、EINTR というのはシグナルでの割り込みのことでしょうか? ( pthread_cond_timedwait が EINTR を返すという記述が見つからなかった… )
次に、「条件変数を…」というのは、「pthread_cond_* はキャンセルポイントになるので、pthread_cleanup_push でハンドラを登録しておけば後始末ができるよ」ということでしょうか? どのように組み込む想定か、ご教示くだされば幸いです。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2008-07-04 22:07
引用:

angelさんの書き込み (2008-07-04 18:10) より:
そうすると、スレッドのキャンセルが絡む時の事を考えて、mutex での長時間のロックはしない、ということになるのでしょうか。
Two-Phase Termination のお話が出る、ということは、やはりスレッドのキャンセルが行われる、という前提なのでしょうし。



他に理由が思いつかなかったからです。
実際のところ、どうなんでしょうかね?

ご存じだとは思いますが、Two-Phase Terminationによる終了と、
pthread_cancel(3)によるキャンセルは全く別物ですよ。

外部からの強制終了は極力避けるべきですが、
各スレッド側が自発的に終了できるようにはすべきです。

引用:

ちょっと分からなかったのが、EINTR の話と、「条件変数を応用したロックであれば、Two-Phase Terminationを組み込むことができる」という下りです。



他の機構でもタイムアウトと組み合わせればTwo-Phase Terminationできますが、
条件変数であればタイムアウトを考慮しなくとも自然に実現できるからです。

ロック制御のフラグのチェックと一緒に終了フラグもチェックするようにして、
終了させる側は終了フラグを立ててpthread_cond_broadcast(3)するだけです。

引用:

まず、EINTR というのはシグナルでの割り込みのことでしょうか? ( pthread_cond_timedwait が EINTR を返すという記述が見つからなかった… )



ええ。シグナルが起こった場合の復帰のアレです。

http://www.linux.or.jp/JM/html/glibc-linuxthreads/man3/pthread_cond_init.3.html
少なくともこのページには書いてありますよ。
1

スキルアップ/キャリアアップ(JOB@IT)