1

以下のコードが示すように、packaged_task を渡して独自のスレッド クラスを実装しようとしています。次に、この packaged_task からの未来を待ちます。このコードが 4 秒待機すると、未来から 0xcdcdcdcd を取得できると予想されます。

#include <iostream>
#include <future>

using namespace std;

class mythread {
public:
    thread internal_thread;
    template <typename _Fn> mythread(_Fn f) {
        internal_thread = thread([&f] {
            try {
                f();
            }
            catch (std::exception& e) {
                this_thread::sleep_for(chrono::seconds(4));
                std::cout << e.what() << std::endl;
            }
        });
    }
};

int work() {
    this_thread::sleep_for(chrono::milliseconds(2000));
    return 0xcdcdcdcd;
}

int main() {
    packaged_task<int()> task(work);
    future<int> ftr = task.get_future();
    mythread thrd(move(task));

    ftr.wait();
    cout << "Got it!!" << endl;
    try {
        cout << ftr.get() << endl;
    }
    catch (future_error &e) {
        std::cout << "outer " << e.code() << e.what() << std::endl;
    }
    cout << "Ended" << endl;
    getchar();
}

しかし、待機はこのタスクをすぐに終了するようです。このコードを実行してコンパイルすると、すぐに出力されます

Got it!!
outer future:4unspecified future_errc value

Ended

環境はOS X 10.11.1、

$ g++ -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin15.0.0
Thread model: posix

コンパイルコマンドは

g++ --std=c++11 main.cpp && ./a.out

他のプラットフォームで再現されるかどうかはわかりません。

前もって感謝します。

編集

解決済み: これは、現在のコンストラクターが、スレッドによって参照が使用されている、移動されたの有効mythread期間を制御するためです。fただし、コンストラクターはスレッドを作成した直後に戻るため、スレッドが破棄されfたローカル変数を保持している間、 を含むすべてのローカル変数が破棄されます。

修正したコードは

class mythread {
public:
    thread internal_thread;
    template <typename _Fn> mythread(_Fn f) {
        internal_thread = thread([] (_Fn f) {
            try {
                f();
            }
            catch (std::exception& e) {
                this_thread::sleep_for(chrono::seconds(4));
                std::cout << e.what() << std::endl;
            }
        }, move(f));
    }
};

の制御fがさらにスレッドに移動する場所。

4

0 に答える 0