- - PR -
pthreadの読み込み/書き込みロック
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-06-27 23:21
こんばんは。
最近プログラミングもやるようになりました。 pthreadの排他制御で疑問が出たところがありますので、どなたかご教示頂ければ幸いです。 1. 作っているもの 同じ動作を複数スレッドで、並列非同期に繰り返し行うプログラム ( 負荷生成ツール ) 2. 考えている仕組み 各スレッドでの負荷生成状況 ( 単位時間当たりの正常処理件数/エラー件数、処理時間平均等 ) をとりまとめてレポートできること。 各スレッドは、スレッド毎に決められたメモリ領域に非同期に状況を記録し、周期的にレポート用スレッドが、それら記録された情報を読み込み、集計の上レポートする。 ※レポート用スレッドを立てずに全スレッドが printf等を行った場合、集計が面倒と思われるため 3. 疑問点 負荷生成スレッドが状況を記録する動作と、レポート用スレッドがそれら情報を読み込む ( 情報のリセットも含む ) 動作が競合するため、排他制御を行う必要があると考えていますが、そこで読み込み/書き込みロックは使えるものでしょうか。 mutexをスレッド数分用意するのは、オーバーヘッドが大きいのではないかと考えています。 もしくは単一のmutexで、状況記録そのものを同期的に行う手もありますが、せっかく負荷生成を非同期に行っていても、レポートの部分がジャイアントロックになると無駄が多いのではないか、とも考えています。 で、読み込み/書き込みロックを使用する方式としては、状況記録時は、各負荷生成スレッドで pthread_rwlock_rdlock による読み込みロックを取得、集計用スレッドは、定期的に pthread_rwlock_wrlock で書き込みロックを取得し、各スレッドの記録した情報を収集する、というものを考えました。 各負荷生成スレッドでの状況記録は並列に行え、情報収集時のみは、状況の記録がブロックされるということで、都合が良さそうだと考えています。 この方式で問題はなさそうでしょうか。特に、処理としての読み書きと、ロックの種類(読み書き)が逆になってしまいますが、この点は如何でしょうか。 また、これ以外で定石となっているような方法があれば、是非ご教示ください。 | ||||||||
|
投稿日時: 2007-06-28 11:09
・負荷生成スレッドは状況を記録する ・レポート用スレッドはリセットする どちらも書き込み動作を含んでいるのでrwlockは有効でないと思います。
複数のmutexにロックを分散させる方法ですね。 一般的にはこちらに近い形を使うことが多いようです。 mutexは同期機構の中では軽い部類のオブジェクトなので、 全スレッドに対応する数を使っても一般的に問題ありません。 mutexの数を減らしたいのならば、ハッシュ法を応用して、 同期化する対象のハッシュ値からmutexを求める方法が使えます。 angelさんの場合ですと、 スレッド毎に用意した統計情報が同期化する対象なので、 ここに連番でもスレッドIDでもよいので整数の識別IDを用意して、 mutexの配列[識別ID % 配列の要素数]として得たmutexをロックします。 こうすれば、スレッド数に影響されずに、 任意の数のmutexにロックを分散させることができます。 | ||||||||
|
投稿日時: 2007-06-28 20:01
clone(3)しか使わない野蛮人なので、文明的な方法はあまり分からないですが。
> 特に、処理としての読み書きと、ロックの種類(読み書き)が逆になってしまいますが、この点は如何でしょうか。 べつに問題ないかと。pthread_rwlock_rdlockとかpthread_rwlock_wrlockとか いってるのは、shared lock と exclusive lock の組み合わせをどう操作するか という話で、読み込み時に利用するのに向いていそうな操作をpthread_rwlock_rdlock、 書き込み時に利用するのに向いていそうな操作をpthread_rwlock_wrlockと 呼んでいるだけのことで、ロックを取って何をしようがどうでもいいことですよね。 > mutexをスレッド数分用意するのは、オーバーヘッドが大きいのではないかと考えています。 ロックの取得を試みるところで無駄にループして重くなるのではないか、 ということでしょーか。ロックを確保しているのが短時間であれば 問題は生じないし、この場合はごく短時間でよさそうですよね。 あとは、ロックを取らずにやる、とか。 必要な情報をビット演算してひとつの変数に詰め込んで、アトミックに メモリアクセスするように書くという手です。 インラインアセンブラ書いたりで、可搬性は犠牲になりますが。 個人的には > ※レポート用スレッドを立てずに全スレッドが printf等を行った場合、集計が面倒と思われるため というのがどうにもピンと来ませんが。 スレッド別に生の情報をファイル出力してもいいし、ひとつのファイルを 共有してwrite(2)でアトミックに書き込むようにしてもいいし、 それを後から集計すればいいんじゃないかしらん。 |
1