0

私はC++ 11スレッドの初心者で、クラスのメンバー関数を使用して同時スレッドで実行しようとしています。

以前の質問への回答で、次の提案を受け取りました。

std::thread t1(&SomeClass::threadFunction, *this, arg1, arg2);

上記の提案を実行しました。発生していたコンパイル エラーは解消されましたが、実行時エラーが発生しました。別の質問で、すべてのコピー メカニズムを削除するよう提案を受けました。実際には、コードは有限要素解析用であり、多くのメモリを必要とするため、データをコピーしたくありません。

これを行う方法はありますか?

ヘッダーは次のようになります。

SomeClass {
    vector<int*> someVariable;
public:
    ~SomeClass();
    void threadedMethod(bool, bool); // Inside this method the 
                                     // member vector 'someVariable' is used.

    void someMethod();               // In this function the threadedMethod has
                                     // been used twice to make 2 different thread
};

someMethod の実装は、

void SomeClass::someMethod() {
    thread t1(&SomeClass::threadedMethod, *this, arg1, arg2);
    thread t2(&SomeClass::threadedMethod, *this, arg1, arg2);
    t2.join();
    t1.join();
}

デストラクタは次のようになります。

SomeClass::~SomeClass() {
    int count  = someVariable.size();
    for(int i=0; i < count; i++) {
        delete someVariable[i];
    }
}

threadMethod は変数にアクセスします。操作はデータ並列です。その結果、どのスレッドも同じメモリ ブロックに書き込みません。繰り返しますが、読み取りメモリと書き込みメモリは異なります。そこには、どんな種類のロックも必要ないと思います。

ご覧のとおり、私は使用して*thisおり、それが多くのコピーを引き起こしています。私は本当にそれを避ける必要があります。コピーを回避できる他の方法を親切に提案できますか?

さらに説明が必要な場合は、お知らせください。私の能力の範囲内であれば、可能な限り詳しく説明しようとします。

OS X 10.8.3 を搭載した Intel Mac を使用しています。Xcode 4.6.1 でコーディングしています。コンパイラは Apple LLVM 4.2 (デフォルト コンパイラ) です。

4

1 に答える 1

3

引数は、値によってコンストラクターに渡されますstd::thread。したがって、このステートメント:

std::thread t1(&SomeClass::threadFunction, *this, arg1, arg2);
//                                         ^^^^^

のコピーをトリガーしますが*this、これは必要なものではありません。ただし、とまったく同じように、メンバー関数が呼び出されるオブジェクトへのポインターstd::threadを受け入れることもできます。std::bind

したがって、this( の代わりに*this) を引数として渡すと、指定されたオブジェクトではなくポインターが値によって渡され、最終的にコピーされます。これにより、必要に応じて のコピー構築がトリガーSomeClassされません。

したがって、上記のステートメントを次のように書き換える必要があります。

std::thread t1(&SomeClass::threadFunction, this, arg1, arg2);
//                                         ^^^^
于 2013-04-01T07:44:13.610 に答える