これは、「単純に明白ですが、おそらく間違っている」カテゴリに分類されるように思われる質問の1つです。確かに、私はすべてのコーナーケースで機能する解決策を見つけるのに苦労しています。これは常に遭遇する問題のようです。
「ハードウェア」スレッドと「処理」スレッドがあります。
ハードウェアスレッドは、私がアクセスできない閉じたバイナリライブラリで実行されます。
処理スレッドは、ハードウェアの状態変化に関連する特定の(まれな)イベントを通知するために、ハードウェアスレッドにコールバックを登録します。
状態が変化したことを処理スレッドのイベントループに通知できるようにしたいと思います。外部ライブラリに依存したり、移植性のない方法で、ロックを使用せずにこれを実行したいと思います(ハードウェアスレッドがいつ処理スレッドに再度通知するかわからないため)。
それで、これをどのように解決するかについての現在の私の考えは次のようなものです:
#include <signal.h>
// sig_atomic_t is used so update is always in a sane state
static volatile sig_atomic_t update = 0;
// called from hardware thread
int callback_function() {
update += 1;
}
// called regularly from processing thread
int processing_function() {
static sig_atomic_t local_update = 0; // The same type as update
if (local_update != update){
update_internal_hardware_state(); // We necessarily call once per callback
local_update += 1;
}
}
明らかに、これがupdate
ラップアラウンドし、次に呼び出されるlocal_update
前の値にたまたま到達した場合、これは壊れますprocessing_function
(ただし、ほぼ確実に、これは決して発生しないと想定できます)。
ここで微妙な(またはそれほど微妙ではない)何かを見逃したことがありますか?
この問題全体を解決するためのより良い方法はありますか?
コールバックは、1つのスレッド(ハードウェアスレッド)からのみ呼び出されると想定できます。