C++ 一个简单的pthread_创建导致Qt中100%的CPU使用率

C++ 一个简单的pthread_创建导致Qt中100%的CPU使用率,c++,c,linux,qt,pthreads,C++,C,Linux,Qt,Pthreads,当一个简单线程运行时,其中只有一个无限循环,导致100%的CPU,这怎么可能呢 我的线程调用如下所示,在Qt对话框类中的QEvent上,比如说单击按钮 pthread_t thread_id; pthread_create( &thread_id, NULL, DataCollectionThread, (void*) this ); 我的线程程序是 void* DataCollectionThread( void* pParam ) { ((m_DataCollecti

当一个简单线程运行时,其中只有一个无限循环,导致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使用率为100%时,打印之间的任何硬件中断都会导致打印暂停,因为CPU会将任务切换到处理中断

我在基于Qt::Dialog的类中调用此线程。我敢肯定,除了这一点之外,不会触发其他任何东西。这个怎么了?一个简单的无限循环会导致100%的CPU消耗吗?或者在Qt中使用pthread_create有什么问题吗

编辑:乔纳森·莱因哈特

这是实际的while循环

while( 1 )
    {

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



        if(!m_DataReadable)
            break;
      }

将执行以下操作:

1. Does the number 1 equate to true?
2. Yes.
3. Go to 1.
每当线程执行时,CPU都将持续执行此操作。为什么你启动一个线程只是为了把它放在一个没有任何作用的旋转循环中?

是的

将执行以下操作:

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

每当线程执行时,CPU都将持续执行此操作。为什么启动一个线程只是为了将它放入一个不起任何作用的旋转循环中?

一个简单的解决方法是:短时间睡眠,让CPU做其他事情。在循环中包括并添加以下内容:

struct timespec ts;
ts.tv_sec=0;
ts.tv_nsec=10000000; // 10 milliseconds
nanosleep(&ts, NULL);
当然,如果您可以显式地睡眠,直到您有实际的工作要做更多的输入来读取,一个完整的队列要修剪,这会更好。但增加短期睡眠可能就足够了


研究m_pDataProvider对象的实现可能是有意义的。检查或添加一种方法,允许您睡眠,直到有更多数据。如果您只是从字符设备(如ttyS0)读取数据,轮询或选择在这里可能很有用。

一个简单的解决方法是:短时间睡眠,让CPU做其他事情。在循环中包括并添加以下内容:

struct timespec ts;
ts.tv_sec=0;
ts.tv_nsec=10000000; // 10 milliseconds
nanosleep(&ts, NULL);
当然,如果您可以显式地睡眠,直到您有实际的工作要做更多的输入来读取,一个完整的队列要修剪,这会更好。但增加短期睡眠可能就足够了

研究m_pDataProvider对象的实现可能是有意义的。检查或添加一种方法,允许您睡眠,直到有更多数据。如果您只是从字符设备(例如ttyS0)读取数据,轮询或选择在这里可能很有用。

与此不同,真正支持操作系统的线程允许CPU中断这样锁定的代码。所以你的电脑没有完全消亡。但会出现一些退化。如果有工作要做,计算机没有一个很好的方法知道不要尽全力运行它给出的代码…缺少像这样的调度工具

有时,您可以通过线程优先级来缓解类似问题。Qt有一个抽象概念,但请注意它说:

优先级参数的效果取决于操作系统的调度策略。特别是,在不支持线程优先级的系统(如Linux)上,优先级将被忽略,有关更多详细信息,请参阅

似乎Qt的人在linux和linux下查看了线程优先级。因此,如果这是您的平台,那么您可能应该设计您的系统,使其不会像这样旋转

如果您将ReadData更改为

这是我尝试使用@jweyrich刚刚提到的sched_成品更有效的方法。

与之不同,真正的操作系统支持的线程允许CPU中断这样锁定的代码。所以你的电脑没有完全消亡。但会出现一些退化。如果有工作要做,计算机没有一个很好的方法知道不要尽全力运行它给出的代码…缺少像这样的调度工具

有时,您可以通过线程优先级来缓解类似问题。Qt有一个抽象概念,但请注意它说:

优先级参数的效果取决于操作系统的调度策略。特别是,在不支持线程优先级的系统(如Linux)上,优先级将被忽略,有关更多详细信息,请参阅

似乎Qt的人在linux和linux下查看了线程优先级。因此,如果这是您的平台,那么您可能应该设计您的系统,使其不会像这样旋转

如果您将ReadData更改为


这是我尝试使用@jweyrich刚才提到的sched_产量更有效地完成的方法。

while1==100%单核cpu负载,但由于cpu使用率为100%,打印之间的任何硬件中断都会导致打印暂停,因为cpu会将任务切换到处理中断。对我来说,这似乎是一个相当可疑的解释。你到底看到了什么?口吃?绘图刚刚完成

伊利停下来了?事实上,我怀疑你看到的任何问题的真正原因是你对LockLeadData后面的互斥锁进行了严重的破坏。所谓暂停,我的意思是,例如,当我在打印时连接usb,打印在自动安装usb时只会暂停几秒钟,然后在绘制一些噪声后返回正常状态。即,暂停几秒钟,绘制噪声值几秒钟,然后绘制正常值。最让我吃惊的是我得到的噪音值。此USB接口是否会在串行设备中引入任何噪声?最重要的是,我的开发工具包中的处理器只有1GHz单核:,这进一步增加了复杂性。@Managu,你对这个噪音问题有什么猜测吗?我认为你没有提供足够的信息让我评论你的噪音问题。例如,您实际试图绘制什么图形,您的输入如何转换为程序中的数据,可能涉及到什么实际硬件等。此外,解决此类问题最好在单独的问题中完成。while1==100%单核cpu负载,但由于cpu使用率为100%,打印之间的任何硬件中断都会导致打印暂停,因为CPU会将任务切换到处理中断。对我来说,这似乎是一个相当可疑的解释。你到底看到了什么?口吃?阴谋完全停止了?事实上,我怀疑你看到的任何问题的真正原因是你对LockLeadData后面的互斥锁进行了严重的破坏。所谓暂停,我的意思是,例如,当我在打印时连接usb,打印在自动安装usb时只会暂停几秒钟,然后在绘制一些噪声后返回正常状态。即,暂停几秒钟,绘制噪声值几秒钟,然后绘制正常值。最让我吃惊的是我得到的噪音值。此USB接口是否会在串行设备中引入任何噪声?最重要的是,我的开发工具包中的处理器只有1GHz单核:,这进一步增加了复杂性。@Managu,你对这个噪音问题有什么猜测吗?我认为你没有提供足够的信息让我评论你的噪音问题。例如,您实际试图绘制什么图形,您的输入如何转换为程序中的数据,可能涉及到什么实际硬件等。此外,解决此类问题最好在单独的问题中完成。我不知道这个循环会导致100%的CPU。实际上,有从串行端口收集数据的代码,而且我在flag的帮助下绘制了一段时间后正在中断循环。但只要cpu在这个while循环中,它就会消耗100%的cpu。用户代码在等待标志时旋转是不正确的。它只是无缘无故地消耗CPU。我在while循环中添加了确切的代码。再次检查我的问题@spyke:每当线程获得要执行的时间片时,循环都会让处理器忙。您可以通过在循环结束时调用sched_yield来解决此问题。这将产生处理器,并为其他线程/进程提供运行的机会,使您的循环不会消耗所有的能量。如果您愿意,您可以阅读更多有关的内容。如果sched_屈服,您仍然会看到100%的CPU使用率,尽管其他线程可能会变得更灵敏。我不知道这个循环会导致100%的CPU使用率。实际上,有从串行端口收集数据的代码,而且我在flag的帮助下绘制了一段时间后正在中断循环。但只要cpu在这个while循环中,它就会消耗100%的cpu。用户代码在等待标志时旋转是不正确的。它只是无缘无故地消耗CPU。我在while循环中添加了确切的代码。再次检查我的问题@spyke:每当线程获得要执行的时间片时,循环都会让处理器忙。您可以通过在循环结束时调用sched_yield来解决此问题。这将产生处理器,并为其他线程/进程提供运行的机会,使您的循环不会消耗所有的能量。如果你愿意,你可以阅读更多。如果sched_屈服,你仍然会看到100%的CPU使用率,尽管其他线程可能会变得更加响应。我认为这解决了问题。当然,使用睡眠可以大大降低CPU使用率。但它不允许在paintevent运行时处理其他事件[例如,单击按钮]!它只是计划结束,并且仅在paintevent end.wth之后执行?如果没有睡眠功能,则在paintevent处于活动状态时处理所有事件。呃,右:在处理paintevent时不会处理任何GUI交互。构造代码以避免在paintEvent中花费大量时间,例如,让paintEvent只绘制一次图形,使用调用update的函数重写timerEvent,然后在小部件的构造函数中调用setTimer10。也就是说,定期重新绘制图表。我认为这解决了问题。当然,使用睡眠可以大大降低CPU使用率。但事实并非如此
在paintevent运行时,不允许处理其他事件[例如按钮单击]!它只是计划结束,并且仅在paintevent end.wth之后执行?如果没有睡眠功能,则在paintevent处于活动状态时处理所有事件。呃,右:在处理paintevent时不会处理任何GUI交互。构造代码以避免在paintEvent中花费大量时间,例如,让paintEvent只绘制一次图形,使用调用update的函数重写timerEvent,然后在小部件的构造函数中调用setTimer10。也就是说,定期重新绘制图形。