我现在写一个程序,有两个线程:界面线程和工作线程。工作线程用于在后台计算数据,不断地把计算得到的数据打成包以消息的形式发给界面窗口,界面窗口的消息处理函数里显示结果。
    为了不让界面线程因为后台线程CPU占用率过高而死掉,我把后台工作线程的优先级设成最低。本来这样可以工作地得好的,界面操作也很流畅。
    但到了超线程的P4机器上运行时,还是发现界面死掉了,就像根本没开后台线程一样。
    我想了很久,觉得问题可能出在线程调度上。对操作系统来说,HT技术的CPU就是一台双CPU的机器,所以它可以安排这两个线程在“两个不同的”CPU上运行,以便提高效率。但是,实际上还是只有一颗CPU,当系统发现后台线程在一颗只有“一个线程”的CPU上运行时,自然不会去打断它,不管它的优先级有多低,我想这可能就是问题所在,整个CPU还是被后台线程给占掉了。    不知道大家怎么看,或是有什么办法吗?当然,我知道可以强制两个线程在同一个CPU上运行,但这样会影响程序在真正双CPU机器上的运行效果。

解决方案 »

  1.   

    我在超线程的双cpu3。0G的机子起动线程是没有问题啊,是不是你的程序那里可能有问题啊。
      

  2.   

    启动线程当然没有问题,只是我的后台线程是个科学计算的迭代过程,把CPU占光了。
      

  3.   

    建议不要一直不停的运行,过段时间在程序里插一个Sleep(1),效果会好很多
      

  4.   

    插Sleep(1)我试过,有效果,但这样会影响总体性能,这只能作为没办法的情况下的最后一招
      

  5.   

    想办法禁用掉超线程,或者就采用强制在一个CPU上运行的办法。
      

  6.   

    插Sleep(1)我试过,有效果,但这样会影响总体性能????
      

  7.   

    一段循环后插入一个Sleep?当然不要在每次循环中插入Sleep!
      

  8.   

    用Sleep(1)比较好.要么就用event来设置信号吧.
      

  9.   

    呵呵, 在普通CPU上面运行如果没有这现象, 那说明你的代码有问题了吧?
    个人意见而已.
      

  10.   

    可以在cmos中把超线程取消就行了,听说ie导致死机也是超线程的原因.
      

  11.   

    同意医生,busy loop的做法并不妥当,即便在某台机器上似乎能够运行...
    该Sleep的地方就要Sleep.
      

  12.   

    Sleep(1)可以灵活运用,不是死的一定要每次循环都加上一次,可以在运行了比如100次,或者1000次循环后Sleep一次
      

  13.   

    to DentistryDoctor(雅克医生<医德,值得反思>) :
        为什么我的实现方式不妥?不妥在哪里?给个意见好吗?    关掉超线程当然一切正常了。
      

  14.   

    问题已经解决,我插入汇编,使用CPUID指令来检测CPU是否使用HT技术,若使用的话就用SetThreadAffinity来强制前后台线程使用同一个CPU,这样解决有什么问题吗?
      

  15.   

    抛开HT的问题不谈,也应尽可能避免疯狂消耗CPU资源的busy loop,这样给系统的稳定性/可扩展性/移植性都带来很大的影响,换台配置低一点的机器也许都会造成问题.
    busy loop是万不得一走投无路的选择,在多线程设计里面还是应该注意要某些线程合理释放自己的CPU时间,如果Sleep(1)你都觉得长了,也至少应该Sleep(0)一下.
    从方案上来说,处理好后台线程的计算量(减少无用计算),控制好刷新前台屏幕的数据刷新率(刷新率太高没有意义)...从结构上做一些优化应该也是很有意义的.
    而且这里用发消息的方法来通知界面未必妥当,可能造成消息阻塞,界面用(多媒体)定时器来检测数据的变化或者使用信号量效率会好很多
      

  16.   

    我觉得你的程序应该有问题?
    子线程与界面线程的通讯应该是双向的,子线程可以向界面线程发送数据,
    界面线程线程也可向子线程发送命令,比如中断子线程运行等,
    运行WaitForSingleObject这样的同步命令会大大降低CPU的占用率,
      

  17.   

    我想大家误会我的意思了。我不是要降低CPU占用率。
    我的后台线程是一个科学计算的迭代过程,当然算得越快越好,我只是想能在保持界面更新的情况下充分利用CPU的计算资源。
      

  18.   

    一般来说,多线程编程的话,工作线程不会永远的执行,只有当触发一定条件时才进行相应的运算,所以从这方面来说,工作线程不需要工作的时候应在等待,通常应用waitforsingleobject()进行。而不是建立个循环定期进行轮训查找当前是否需要进行计算。所以一般不建议用sleep()等进行。这样需要线程相应的时候或者说要进行计算的时候不是很实时。