原子操作と同時安全
1812 ワード
従来、原子操作と同時安全について誤解していたが、一つの操作が原子ではないと思っていたのは、同時安全ではないと考えていたので、それ以来、ためらっていた.
C言語の簡単な付与文も原子ではありませんか?a=bは原子操作ですか?コードは次のとおりです.
このコードをコンパイルする:g++-c-g-Wa,-adlhn Assign.c > Assign.asm
(a=b部分asmコードのみを表示):
2つのアセンブリ命令で操作が完了し、簡単に説明します. a ==> -4(%ebp) b ==> -8(%ebp) movlはmovパラメータの順序とは逆であり、movl SRC、DEST movl-8(%ebp),%eax=>movl b,%eax(レジスタ%eaxをbに割り当てた値) movl%eax,-4(%ebp)=>movl%eax,a(aの値をレジスタ%eaxの値に割り当てる) この2つの命令により,最終的にa=bの付与が実現された.
だから、a=bは原子ではないと責任を持って言えるようです.
原子ではない以上、同時に安全なのではないでしょうか.もちろん、上記の例は合併とはあまり関係ないようですが、このようなクラスを定義しましょう.
同じようにただ見るだけですv=v部のアセンブル命令
次のように解釈されます. 8(%ebp) ==> _v 12(%ebp) ==> v movl 8(%ebp),%eax=>%eax賦値_vのアドレス movl 12(%ebp),%edx=>%edxはvのアドレス に割り当てられる movl%edx,(%eax)=>%eax対応アドレスの値は%edx対応値 として付与.
過程は実はすべて同じで、説明のために、付与操作は原子ではありません.
もし私の以前の理解であれば、原子操作でなければ同時安全ではありません.同時プログラムはどう書きますか.
実は、これは私の誤解だとしか言えません.まず、どのような状況で同時問題が発生するかをよく考えてみましょう.私の理解では、複数のスレッドがデータを共有することを競争しているときに、同時問題が発生します.振り返ってみると、上のいくつかの行のアセンブリコードを見てみましょう.vは共有データに属し、本当に競争を生み出すことができるのはmovl%edx,(%eax)だけで、この時、複数のスレッドがこのステップの操作をしたいかもしれませんが、実際にはこの操作は原子であるべきでしょう.そのため、このような付与操作は同時安全であるべきです.
C言語の簡単な付与文も原子ではありませんか?a=bは原子操作ですか?コードは次のとおりです.
int main() {
int a = 0;
int b = 2;
a = b;
}
このコードをコンパイルする:g++-c-g-Wa,-adlhn Assign.c > Assign.asm
(a=b部分asmコードのみを表示):
movl -8(%ebp), %eax
movl %eax, -4(%ebp)
2つのアセンブリ命令で操作が完了し、簡単に説明します.
だから、a=bは原子ではないと責任を持って言えるようです.
原子ではない以上、同時に安全なのではないでしょうか.もちろん、上記の例は合併とはあまり関係ないようですが、このようなクラスを定義しましょう.
class CObject {
private:
int _v;
public:
CObject() { _v = 0; }
void putValue(int v) { _v = v; }
int getValue() const { return _v; }
};
同じようにただ見るだけですv=v部のアセンブル命令
movl 8(%ebp), %eax
movl 12(%ebp), %edx
movl %edx, (%eax)
次のように解釈されます.
過程は実はすべて同じで、説明のために、付与操作は原子ではありません.
もし私の以前の理解であれば、原子操作でなければ同時安全ではありません.同時プログラムはどう書きますか.
実は、これは私の誤解だとしか言えません.まず、どのような状況で同時問題が発生するかをよく考えてみましょう.私の理解では、複数のスレッドがデータを共有することを競争しているときに、同時問題が発生します.振り返ってみると、上のいくつかの行のアセンブリコードを見てみましょう.vは共有データに属し、本当に競争を生み出すことができるのはmovl%edx,(%eax)だけで、この時、複数のスレッドがこのステップの操作をしたいかもしれませんが、実際にはこの操作は原子であるべきでしょう.そのため、このような付与操作は同時安全であるべきです.