2017/06/17

[linux]ある区間はスレッドを切り替えて欲しくない場合

まだまだLinuxのマルチスレッドで悩んでいる。


今起きているのは、こういうやつ。

image

丸いのは、mutex_lockだ。
ソケット通信で相手に送るプロセスと、それを受信したらもう片方に中継して送信するプロセスがいて、中継するプロセスはスレッドで相手と接続している。
相手に送信する前にmutex_lockするようにして、lockできたら送信している。


通常はそれでよさそうなのだけど、図のBがほぼ同じタイミングで送信データを受け取ったときに問題が発生した。
Aからの送信をBのA側スレッドが受け取り、ロックを掛けてC側のスレッドに渡そうとするのだが、その直前にスレッド処理がC側スレッドに切り替わり、そちらもロックを掛けてA側のスレッドに渡そうとする、という状況が起きてしまった。。。


こういうときって、どうするのだろうか?
各スレッドを貫くようなmutexを用意して、切り替わって欲しくないタイミングでlockするのがよさそうな気がする。

ただ、こうも思ったのだ。
「スレッドが切り替わらなければいいだけやん」と。
割り込み処理中に多重割込みにならないように割込み禁止にするようなイメージだ。
ディスパッチ禁止とかクリティカルセクションとか、そんな用語でよいのだろうか。


スピンロック、が一番それっぽい気がするが、これはkernelの中でしか使えないのか?
ぐるぐるとループを回して、条件が合うまで抜けない、というシンプルなしくみらしい。
RCUとかいうのもあるが、そもそも読んでいるのが『Linuxカーネル2.6解読室』だから、kernelで使えるしくみを紹介しているのだろう。


などと書いていって気がついたが、そもそも上記の処理ってマルチスレッドにしたのは複数の相手と接続したかったからであって、接続した相手と同時に通信をする必要がないことに気付いた。

つまり、これでいいやん。

image

プロセスとしてmutexを持っていて、誰か最初に処理を始めた人が全部握ってしまえばよいのだ。
終わってから動いたとしてもそれほど問題ない気がする。

整理するって、大切ですね。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。