ncs: スレッドの同期
2024/09/07
マルチスレッドがあるなら、同期機構も備わっている。
同期というとタイミングをそろえるようなイメージがあるのだが、同じリソースに同時にアクセスしないようにしたり、共通で使用しているリソースの解放するタイミングを見計らったり、協調するための機構が大半だと思う。
シングルスレッドでも、割り込みハンドラに処理が遷移することがあるので何らかのディスパッチされずにアトミックに処理する命令などがないと困る。
Lesson 8 – Thread synchronization
出てくるのは定番の semaphore と mutex だ。
Linux の pthread mutex はなんか苦戦した記憶がある。
初期化時にフラグを付けないと私が期待した動作にならなかった、ということしか覚えていない。
デフォルトが fast だから、recursive じゃないとダメだったのだろう。
こちらを見ると、fast だと再ロックしたときにデッドロックするそうだ。
私は lock 中に別の人が lock してきたら、いま lock している人が抜けるまではブロックされていてほしいのだ。
ただ、recursive ということは同じスレッドが再帰的に lock を呼び出していたということ?
当時がどういう状況だったかわからないので忘れよう。
それにしても、私の学生の頃から semaphore と mutex はあったと思うが、今も新しい機構は生まれていないのだろうか。 そんなこといったら未だにノイマン型から逃れられていないし、いろいろ余地はあるんだろうね。
Semaphores
semaphore は旗の上げ下げで、P とか V とかなのは東欧の方で生まれたからだったか。
ダイクストラ先生だった。
そして P と V はオランダ語に由来していた。
調べて良かった。。。
個人としては semaphore はほとんど使ったことが無い。 「この領域を使えるのは同時に一人だけ」みたいな感じでやってるからだと思う。
- ここでは “Give” がインクリメント、”Take” がデクリメントになっている
- “Give” は ISR でもスレッドでも実行できるが “Take” はスレッドでのみ使用可能
- semaphore に所有権という概念はない
- 誰が所有(“Take”)しても良いし、誰が返却(“Give”)しても良い
アトミックなカウンター操作ができるようにするのと、”Take” のときにカウント値がマイナスになるようだったら処理をブロックする機構がある
Mutexes
semaphore の 1つバージョンが mutex くらいの印象なのだが、semaphore がリソースを確保している人なら誰でも解放できるのに対して、mutex は資源を確保できるのは一つのスレッドだけで、解放できるのも確保したスレッドだけになっている。
ただ semaphore も資源を確保しないと解放できないので同じような感じもする。 文章では「semaphoreとは対照的に(as opposed to semaphores)」といっているので、semaphore では確保した資源を別のスレッドなどに渡すことができるのかもしれない。 ISR は “Give” できても “Take” できないので、そういうことをいっているのかもしれない。
- mutex は ISR では使えない
- reentrant loking、となっているので、同一スレッドからの lock も受け付けるが他スレッドと同様にブロックされるということだろう
- 種類に関するオプションがないので、常にそうなのだろう。
- lock にはタイムアウトがある
k_mutex_lock()
- 型はk_timeout_tで、
K_MSEC()
K_FOREVER
でタイムアウト無しになるようだ
- 型はk_timeout_tで、
2024/09/08
Exercise 1
semaphore の実習。
- 10個だけあるリソースを確保するスレッドと解放するスレッド
- consumer: 確保
- producer: 解放
- 「開放」でも「解放」でもよいと思うが、私は「捕らわれていたリソースを解き放つ」というイメージなので「解放」を使っている。
- 乱数(
sys_rand32_get()
)を使うためにprj.conf
でCONFIG_ENTROPY_GENERATOR
とCONFIG_TEST_RANDOM_GENERATOR
を追加してある。- CONFIG_ENTROPY_GENERATOR
- CONFIG_TEST_RANDOM_GENERATOR
- “non-random number generator” だそうな
- だったら
CONFIG_ENTROPY_GENERATOR
はいらないんじゃないか?
- カウント値を自分で持っているが、これはサンプルのためだろう
- k_sem_count_get()で内部管理しているカウント値が取れるようだ
Exercise 2
mutex の実習。
prj.conf
にCONFIG_MULTITHREADING=y
を追加するよう書かれている- が、デフォルトで
y
なので特に書かなくても良い。
- が、デフォルトで
これで DevAcademy の nRF Connect SDK Fundamentals は I2C 以外終わった。
I2C はデバイスが引き出しのどこかにはあると思うが、発掘が難しい。。。