私は内部ライブラリを制御したり知っていない外部ライブラリを使用しています(proprietarycallbacksと呼ぶことができます)。異なるバージョンでコンパイルされた同じコードは異なる結果を提供します
私は私は2つのブール変数を持つクラスと呼ばれるコールバックしていることを知っている:そして、私は、コールバッククラスから継承する別のクラス持っ
class callbacks : public proprietarycallbacks {
bool a = false;
bool b = false;
virtual callbackHandler() {
cout "callback received\n";
b = true;
}
}
を:
class MyObject : public callbacks {
void test() {
while (!b) {
cout << "test " << a << " " << b << endl;
usleep(100000);
}
}
}
をこのコードはで正しくコンパイル2つの異なるGCCバージョンとLIBCバージョンの2つの異なるLinuxバージョン。
最新のもの(linux mint、GCC 5.4 LIBC 2.23)で、私はこのアプリケーションを実行します.coutを参照してください。コールバックが呼び出されると、そのコードはその間存在します。
古いもの(debian、GCC 4.9.2、LIBC 2.19)では、whileは決して存在しません。コールバックの中からプリントを見ることはできますが、変数は常にfalseです。
私はコードと変数の継承を構成する方法に何か問題がありますか、これは私が使用しているソフトウェアのバージョンと関係がありますか?
は、それが関与する複数の実行スレッドがあることをごtest()
方法から明らかなお時間を
'b'の設定と' a'のテストはタイプミスですか?同じスレッド上のコールバックとループもですか? –
変数を 'std :: atomic_bool'に変更すると、その違いは消えますか? –
(前述のtypoが実際にはタイプミスであると仮定します) 'test()'と 'callbackHandler()'が別のスレッドから呼び出されたとすると、 'a'への同時読み書きを行います。期待どおりに動作することは保証されません。提案されているように 'std :: atomic_bool'で何が起こるかを知ることができます。単に' a'を 'volatile'と宣言するだけでも可能です。 1つのコンパイラバージョンが、ループ内で「a」が変化していないと判断し、それをループから読み続けることは非常に可能性があります。メモリの代わりにレジスタ。 – jdehesa