3

いくつかのスレッド化チュートリアルを実行しましたが、1 つのことに興味があります。

std::thread Child([](){ std::cout << "When am I executed?" << std::endl << std::endl; });

//Some other code

Child.join();

//I'm guessing now my thread would be running

私が呼び出したときにスレッドが実行されていますjoin()か、それともスレッドを作成してから join を呼び出したときまでの間にスレッドが実行されていますか? が呼び出されたときに実行される場合join()、私の理解を確認するために、その部分を実行するように指示し、プログラムはメインスレッドで続行され、最終的に子スレッドはメインスレッドが使用している同じメモリで何らかの作業を行いましたか?

ジェネリック クラスのラッパーを作成したい場合は、以下のようなことをしたいのですが、完全には理解できないようです。メモリの観点からスレッドを管理することに混乱しています。

class Sync {
private:
    int val;

public:
    Sync() : val(0) {}
    void Inc() {val++}
    int Value() { return val; }
};

class Async {
private:
    Sync Foo;
    std::mutex mtx;
    std::vector<std::thread*> Children;
public:
    //I would need a new thread each time I called Inc
    void Inc() { 
        Children.push_back(new std::thread([&]() {
            mtx.lock();
            Foo.Inc();
            mtx.unlock();
        }));


    }
    //But how do I know when it is safe to delete Child?  
    int Value() { 
        for(auto& thds : Children) {
            thds->join();
            delete thds; 
        }
        Children.clear();
        return Foo.Value(); }
};

Child が不要になるため、適切な場所はスレッド関数の最後にあるのではないかと考えていましたが、スレッド自体を破棄しようとするとどうなりますか? 私はそれが聞こえるのと同じくらい悪い考えになると思います. スレッドを削除してもよいかどうかを知るにはどうすればよいですか? より良いアプローチはありますか?

以下の提案を反映するように上記のコードを変更しました。

例外のスローに関してチュートリアルが何について話しているかを理解したので、mtx.lock() ではなくミューテックスガードを使用する必要があります。

4

4 に答える 4

4

オペレーティング システムは重要ですが、むしろ普遍的です。スレッドの実行がスケジュールされます。オペレーティング システムが実際に動作するようになる時期は、まったく予測できません。現在広く利用可能な複数のコアを備えたマシンで「迅速に」実行できる可能性は十分にあります。

thread::join() は、スレッドが実行を終了したことを保証するだけです。実際にこのようなコードを書くことはありません。スレッドを開始してから完了するまで待つのはまったく無意味です。スレッドのコードを直接実行することもできます。スレッドを作成してオペレーティング システムを停止させることなく、同じ結果が得られます。

于 2013-10-23T22:05:32.887 に答える
1

スレッドがどの順序で、またはどのコアで実行されるかを知ることはできません。

posix スレッドは基本的に、ヒープを別のスレッドと共有するプロセスとして Linux によって処理されます。カーネルはそれらをスケジュールし、使用するコアを決定します。たとえば、生成された (保護された) アセンブリを見ると、「マルチコア/マルチスレッド プログラミング」は表示されません。これはカーネル レベルで行われるためです。

これが、結合などの機能やミューテックス/セマフォなどのアーティファクトが存在する理由です。競合状態やその他の関連するものを処理するため。

于 2013-10-23T22:03:49.823 に答える
1

join() を呼び出したときにスレッドが実行されていますか?それとも、スレッドを作成してから join を呼び出したときまでの間にスレッドが実行されていますか?

使用可能なリソースに応じて、スレッドの作成後にスレッドが実行 (開始) されます。これには時間がかかる場合があります。このjoin()メソッドは、スレッドが作業を完了するまで待機 (ブロック) します。

提案: 変数にSyncobjectという名前を付けません。キーワードThisが存在するため、紛らわしいです。this

std::threadを呼び出しjoin()た後、オブジェクトを安全に削除できAsync::Inc()ます。さらに、参照をメンバー変数として保存する必要はありません。参照はその関数でのみ使用されます。

<atomic>ヘッダーstd::atomic<int>またはstd::atomic_int. _

于 2013-10-23T22:04:53.360 に答える