2

私のコードには、静的ランダムエンジンジェネレーターで動作する関数があり、ユーザーがメインのスレッドとは異なるスレッドからこの関数を呼び出そうとすると、エラーをスローできるようにしたいと思います。

例として、次の関数を検討すると、次のようになります。

void f()
{
    if (/* SOMETHING */) {
        throw std::future_error("ERROR = f() : cannot be executed in parallel");
    }
}

何でしょう/* SOMETHING */か?

4

3 に答える 3

2

あなたが達成しようとしていることは非常にエレガントだとは思いませんが(スレッドローカルストレージを使用するなど、スレッドごとにランダムエンジンジェネレーターの状態をロックまたは保存する方が良いかもしれません)、ここであなたが求めたものに対する解決策があります:

static const auto mainThreadId = std::this_thread::get_id();

void f()
{
    if (std::this_thread::get_id() != mainThreadId) {
        throw std::future_error("ERROR = f() : cannot be executed in parallel"
            "/from a thread other than the main one");
    }
}
于 2013-01-28T12:43:14.140 に答える
2

私はスレッド化の経験はあまりありませんが、シングルトンやその他の設計パターンに沿って何かをしたいという誘惑にかられます。

そうは言っても、私はこのアイデアが非常に洗練されているとは思いません。なぜあなたがこれをやろうとしているのかわからないので、代替案を提案する方法がわかりません...

メインでシングルトンを作成できると思いますが、他のスレッドから f を呼び出そうとする試みは防止されます。

シングルトンは通常誤用されるので...注意してください。

于 2013-01-28T00:23:03.130 に答える
1

はるかに優れた解決策は、乱数の取得をスレッドセーフにすることです。

これは、次の 2 つの方法のいずれかで実行できます。

  1. 乱数の取得時にミューテックスを取得します。
  2. 乱数を生成する必要があるスレッドには、独自のランダム オブジェクトを与えます。

#1について話しましょう。乱数を取得するために呼び出しをラップすることを提案しているので、これらの呼び出しをミューテックスでラップするのはそれほど大げさではありません。実行時にユーザーに問題を提示するだけではなく (これは一般的に非常に不適切な開発の選択です)、代わりに問題を解決しました。唯一の欠点は、乱数ジェネレーターの呼び出しが遅くなったことです。これはおそらく許容できますが、そうでない場合は、オプション #2 を使用します。

そして、#2について...これは静的乱数ジェネレーターだとおっしゃっています。おそらくそれは、別のコピーを作成できないことを意味しますが、とにかく言及する価値があります。randsrand、こんな感じです。ただし、C++11 のようなものを使用している場合は、std::uniform_int_distributionスレッドごとにコピーを作成しても問題ありません。std::thread_local(各スレッドのコピーを配置する適切な場所が見つからない場合は、検討してください。)

于 2013-01-28T23:39:17.420 に答える