12

私はこれを読んでいました: http://en.wikipedia.org/wiki/Thread_safety

次の関数はスレッドセーフですか?

void foo(int y){
    int * x = new int[50];
    /*...do some stuff with the allocated memory...*/
    delete [] x;
}

この記事では、スレッドセーフにするためにスタックからの変数のみを使用できると述べています。本当に?なんで?上記の関数の後続の呼び出しは、メモリを別の場所に割り当てませんか?

編集:ああ。記事のこの部分を読み間違えたようです。

サブルーチンは再入可能であるため、スレッドセーフです。

  • 使用する変数はスタックからのものだけです

(という意味にとった

サブルーチンは再入可能であり、したがってスレッドセーフです。

  • 使用する変数はスタックからのものだけです

、以下の回答によると、そうではありません)

4

3 に答える 3

13

newマルチスレッドをサポートする環境でコーディングしている場合は、スレッド セーフであると確信できます。

メモリはヒープ上にありますが、それへのポインタはスタック上にあります。スレッドのみがこのメモリへのポインタを持っているため、同時変更のリスクはありません。他のスレッドは、メモリがどこで変更されるかを知りません。

このポインターを別のスレッドに渡し、別のスレッドが元の (または別の) スレッドと同時にこのメモリを同時に変更する場合にのみ、スレッド セーフの問題が発生します。

于 2010-05-17T00:01:11.307 に答える
2

スタック変数しか使用できないとは言っていません。

newdelete通常、スレッドセーフな方法で実装されているため (ただし、標準で保証されているかどうかはわかりません)、上記のコードはおそらく問題ありません。

さらに、配列を手動で割り当てる代わりに使用するという通常の推奨事項ですstd::vectorが、例としてのみ提供したと思います:)

于 2010-05-17T00:00:11.567 に答える
1

new と delete は、スレッドセーフな場合とそうでない場合があります。おそらくそうですが、それは実装に依存します。参照: Linux および gcc 4 での C++ の新しい演算子のスレッド セーフ

スレッド セーフにするために、関数はスタック変数を使用するか、他のリソースへのアクセスを他のスレッドと同期する必要があります。異なるスレッドから呼び出されたときに new を個別に呼び出してヒープに異なるスペースを割り当てる限り、問題はありません。

于 2010-05-16T23:58:43.147 に答える