1

スレッドとミューテックスがどのように機能するかを学習しようとしていますが、現在、少し混乱している穴にぶつかっています。公式の SFML 1.6 チュートリアルから次のコードを取得しました。

#include <SFML/System.hpp>
#include <iostream>

void ThreadFunction(void* UserData)
{
    // Print something...
    for (int i = 0; i < 10; ++i)
        std::cout << "I'm the thread number 1" << std::endl;
}

int main()
{
    // Create a thread with our function
    sf::Thread Thread(&ThreadFunction);

    // Start it !
    Thread.Launch();

    // Print something...
    for (int i = 0; i < 10; ++i)
        std::cout << "I'm the main thread" << std::endl;

    return EXIT_SUCCESS;
}

そしてそれは言った

したがって、両方のスレッドからのテキストが同時に表示されます。

ただし、それは起こっていません。最初に最初のスレッドを実行し、次に 2 番目のスレッドを実行しますが、同時に実行する必要はありませんか? Windows XP SP3 で Codeblocks IDE を使用し、SFML 1.6 を実行しています。私は何か間違ったことをしていますか、それともそれらがどのように機能するかを誤解していますか? 私の観点からは、スレッドは同時に実行されるはずなので、出力は次のようになります

「スレッド 1 のテキスト スレッド 2 のテキスト スレッド 1 のテキスト など」

ここに画像の説明を入力

4

1 に答える 1

4

...同時に実行することになっていないのですか?

まあ、それは異なります。

2つ以上のコアがある場合、それら同時に実行される可能性があります。

利用可能なハードウェアがある場合でも、スレッドのスケジュール方法を決定するのはOS次第です。OSに両方のスレッドをインターリーブするように促す場合(追加の作業なしでは強制できません)、またはsleepを追加してみてください。ループ(正確なプリミティブはプラットフォームによって異なります)。nanosleepyield


カーネルがスケジューリングを決定する方法と理由についての直感を構築するのに役立つ場合、ほとんどのCPUアーキテクチャは、単一スレッドの最適化に非常に優れた大量の状態(分岐予測テーブル、データ、および命令キャッシュ)を保持することに注意してください。実行。

したがって、回避可能なコンテキストスイッチ、キャッシュミス、および予測ミスの数を最小限に抑えるために、特定のスレッドを特定のコアで可能な限り長く実行する方が一般的に効率的です。

現在、タイムスライシングは、個々のプロセスの最高のスループットと、外部イベントに対する最高のレイテンシまたは応答性との間の一種のトレードオフとしてよく使用されます。スレッドがブロックする可能性があります(ユーザー入力やデバイスI / Oなどの外部イベントを待機することにより、別のスレッドと明示的に同期するか、明示的にスリープまたは譲歩するため)。この場合、別のスレッドはスケジュールされますが、最初のスレッドはブロックできません。進行しますが、それ以外の場合は、通常、割り当てられたタイムスライスの最後にカーネルがプリエンプトするまで実行されます。

親スレッドが子スレッドを作成するとき、現在のコアでどちらが「ホット」であるかを推測したくないので、親にタイムスライスを終了させる(ブロックしない限り)のが妥当なデフォルトです。

子スレッドはおそらくすぐに実行可能ですが、親スレッドをプリエンプトしない場合は、別のコアのスレッドをすぐにプリエンプトする必要がある理由も明らかではありません。結局のところ、それはまだ親スレッドと同じプロセスにあり、同じメモリ、アドレスマップ、およびその他のリソースを共有します。別のコアが完全にアイドル状態でない限り、子をスケジュールするのに最適な場所は、おそらくその親と同じコア上にあります。親がそれらの共有リソースをそこのキャッシュで暖かく保つ可能性が十分にあるからです。

したがって、スレッドがインターリーブされない理由は、プロセスが終了する前にタイムスライスのかなりの部分で実行されず、I / Oをブロックしたり、明示的に生成したりしない可能性があります(stdoutはその量のデータをブロックしていません) 、簡単にバッファリングできるため)。

于 2012-09-17T14:51:48.417 に答える