14

メモリからの読み取りがスレッドセーフではないのはなぜだろうと思っていました。私がこれまでに見た中で、特にこの質問では、メモリからの読み取りはスレッドセーフではないようです。

私はしばらくの間 Python でコーディングしており、現在は C++ に取り組んでいます。Python での読み取りがスレッドセーフではないということは聞いたことがありません。

間違っている場合は訂正してください。そうでない場合は、メモリからの読み取りがスレッドセーフではない理由を教えてください。

4

4 に答える 4

20

読み取りはスレッドセーフです。問題ありません.....読み取り元の場所に何かが書き込まれるまで、そして...データが変更される前に読み取るか、データが変更された後に読み取ることができれば幸いです(このような場合は心配ありません)、しかし、本当に必要のないときに、書き込みの途中で読み取りを行ってから、完全なガベージ データを取得することがあります。

これを軽減する方法は、書き込みの前または後のいずれかのみを読み取るようにすることです。これには、書き込みが発生していることを確認し、何らかの同期ロックを使用する必要があります。ただし、明らかにロックをチェックしてから、読み取りではなく読み取りを行っているため、これにより処理が遅くなります。プリミティブ データ型 (int など) を使用している場合は、CPU 同期を使用してこれを劇的に高速化できます。

fr Python の場合、python データは言語ランタイムによって常に同期される可能性があります。そうでない場合は、遅かれ早かれ同じスレッド読み取りの問題が発生します。(クイックグーグルはイエスと言います。注意しないと、 Pythonも同じ問題に悩まされます)

于 2012-07-25T10:40:21.120 に答える
9

メモリからの読み取りはスレッドセーフですが、同時に書き込み可能なメモリからの読み取りは安全ではありません。

Python では、多くのオブジェクトが不変であるため、これはあまり問題になりません。したがって、これらの場合、メモリ自体ではなく、参照のみが変更されます。

于 2012-07-25T10:35:51.097 に答える
9

多くのスレッドが同じ場所を読み取っている場合、誰もそこに書き込みを試みなくなるまで、スレッドセーフです。

スレッド A が読み取り中のメモリでスレッド B が書き込みを行っているのと同時に何かを読み取っている場合を考えてみましょう。を生成しrace conditionます。読み取り結果が無効になるか、起動ごとに異なる可能性があります

于 2012-07-25T10:34:16.507 に答える
1

同じものを同時に読む - 安全です。問題は、何かが同時にそれに書き込むときです。

次のコードを検討してください。

int arr_len = 3;
int* arr = new int[arr_len];

void thread_1()
{
    std::cout << arr[arr_len-1];
}

void thread_2(int new_len)
{
    int* temp = new int[new_len];
    for(int i = 0; i < arr_len && i < new_len; ++i)
        temp[i] = arr[i];
    arr_len = new_len;
    delete arr;
    arr = temp;
}

arr[arr_len]それが順番に行われるとしましょう(最初arr_lenに読み込まれ、次にarr)。

2 つのスレッドが交互に実行されるとどうなりますか? 次の 3 つのいずれかが発生する可能性があります。

  • 問題ありません - あなたはラッキーです!
  • arr_lenより大きいarr- UB :(
  • arr無効化された (削除された) - UB :(
于 2016-07-07T18:14:52.857 に答える