1

100% の CPU を引き起こす無限ループだけで単純なスレッドを実行すると、どうしてこれが可能になるのでしょうか?

私のスレッド呼び出しは、QtダイアログクラスのQEventで次のようになります。ボタンクリックで言います。

  pthread_t thread_id;
  pthread_create( &thread_id, NULL, DataCollectionThread, (void*) this );

そして、私のスレッド手順は、

void* DataCollectionThread( void* pParam )
{
   ((m_DataCollection*)pParam)->m_ReadDatafromport();
   return NULL;
}

そして、これReadData()には...

while(1)
{
}

私の要件は、シリアルポートからデータを収集し、グラフを継続的にプロットすることです。CPUただし、CPU 使用率が 100% であるため、プロットの間にハードウェア割り込みが発生すると、タスクが割り込みを処理するように切り替わるため、プロットが停止します。

Qt::Dialogこのスレッドをベース クラスで呼び出しています。これ以外にトリガーされるものは何もないと確信しています。これの何が問題なのですか?単純な無限ループで 100% の CPU 消費が発生しますか? または、Qt で pthread_create を使用する際に問題はありますか?

編集:ジョナソン・ラインハートの場合

これは実際のwhileループです

while( 1 )
    {

            while(( Dataisavailable))
            {
                 //push the read data to stack
            }



        if(!m_DataReadable)
            break;
      }
4

3 に答える 3

2

協調マルチタスクとは異なり、OS がサポートする真のスレッドでは、CPU はこのようにロックされたコードに割り込むことができます。つまり、コンピュータが完全に死んでいるわけではありません。しかし、多少の劣化は生じます。コンピューターには、やるべき仕事がある場合に与えられたコードを実行するために最善を尽くさないことを知る良い方法がありません...素晴らしいようなスケジューリングツールが不足しています

「スレッドの優先度」を使用すると、このような問題によって引き起こされる問題を軽減できる場合があります。Qt にはQThread::setPriority()抽象化がありますが、次のように記載されていることに注意してください。

優先順位パラメーターの効果は、オペレーティング システムのスケジューリング ポリシーによって異なります。特に、スレッド優先度をサポートしていないシステム (Linux など、詳細についてはhttp://linux.die.net/man/2/sched_setschedulerを参照) では、優先度は無視されます。

Qt の人々は、Linux でのスレッドの優先順位を見て、あきらめたようです。したがって、それがプラットフォームの場合は、このように回転しないようにシステムを設計する必要があります。

変わったらどうなるか気ReadData()になる…

QMutex dummy;
while(1)
{
    QMutexLocker locker (&dummy);
}

sched_yield(これは、 @jweyrich が言及したものでより効果的に実行できる何かを試す私の方法でした。)

于 2012-06-28T05:46:29.867 に答える
1

はい。

while(1) { }

次のことを行う予定です。

1. Does the number 1 equate to true?
2. Yes.
3. Go to 1.

そのスレッドが実行されているときはいつでも、CPU はこれを継続的に実行します。何もしないスピンループに入れるためだけにスレッドを開始するのはなぜですか?

于 2012-06-28T05:23:33.320 に答える
1

これを回避する 1 つの簡単なハック: (短い) 期間スリープして、CPU に他のことをさせます。 #include <ctime>ループのどこかに追加します:

struct timespec ts;
ts.tv_sec=0;
ts.tv_nsec=10000000; // 10 milliseconds
nanosleep(&ts, NULL);

もちろん、実際にやるべき作業があるまで明示的にスリープできる方がよいでしょう (読み取る入力が増え、トリミングするキューがいっぱいになります)。しかし、短い睡眠を追加するだけでおそらく十分でしょう。

m_pDataProviderオブジェクトの実装を調べることは理にかなっているかもしれません。データが増えるまでスリープできるメソッドを確認または追加します。キャラクターデバイス (ttyS0 など) から読み取るだけの場合、pollまたはselectここで役立つ場合があります。

于 2012-06-28T05:46:10.733 に答える