如果优化程序呢?如果优化程序呢?

解决方案 »

  1.   


    目前想到的法子:
    用线程代替 定时器:
    线程函数:
    while(1)
    {sleep(时间);
    }
    方法2:用waitabletime替代,如何?
      

  2.   


    定时器 要管好 别多settimer
      

  3.   

    100+线程,每个线程都有自己的timer,工作很正常,没事。
    你的程序有多少个定时器?间隔多少?
      

  4.   

    你还不如开N个线程while(TRUE)
    {
      if(XXX=“完成”)
        break;
      else
       {
          //做爱做的事情
       }
     Sleep(TIME);
    }
      

  5.   


    不是说sleep的法子会耗cpu吗?
      

  6.   


    不是说wm_timer会消耗 cpu吗?我觉得采用一种设计需要考虑哪方面
    1. 是否过多耗cpu(这是重点)2.是否精确(次要问题)
      

  7.   


    不是说wm_timer会消耗 cpu吗?我觉得采用一种设计需要考虑哪方面
    1. 是否过多耗cpu(这是重点)2.是否精确(次要问题)我说的wm_timer是放在一个主线程里的, 不是子线程里的。别搞混了
      

  8.   

    Sleep()后程序会阻塞,可视为不消耗CPU。
    TIMER消耗CPU多不多,有没有权威说法,比如开发手册明确说TIMER不能多用。如果没有,可以写个程序测试:n个线程,每个线程启动一个TIMER,间隔m秒,ONTIMER什么也不做,看看效果。
      

  9.   


    我提供了代码,帮忙测一下,多谢
    //60 threads to test
    for(int i=0; i<60; i++)
    AfxBeginThread((AFX_THREADPROC)DoNonProc,NULL); static UINT WINAPI DoNonProc(void* pParam);UINT WINAPI CMainFrame::DoNonProc(void* pParam)
    {
    MSG msg;
    static int nTime_ID=0;
    nTime_ID++;
    ::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE);
    ::SetTimer(NULL, nTime_ID, 10000, NULL);
    while (::GetMessage(&msg, NULL, 0, 0))
    {
    ::TranslateMessage(&msg); if (msg.message == WM_TIMER)
    {
    }
    ::DispatchMessage(&msg);
    }
    return 0;
    }
      

  10.   

    600线程,100ms间隔,CPU纹丝不动。
      

  11.   


    第一点:是我的代码有误?还是网上的 说法有误,说什么wm_tiemr处理降低cpu,还会延迟或者抛弃看来不可信第二点:
    我先说说我对wm_timer的理解:wm_timer是一种低优先级的消息, 貌似整个windows中,它和wm_paint是最低的, 所以是最后执行这消息!进入case wm_timer的时候, 如果此时执行了 部分代码, 突然 新的消息进入程序的消息队列中(windows并不会去理解执行新的消息),依然继续执行wm_timer里的代码。  如果这代码耗时,那么就会影响到 上面提到的新的消息了, 比如界面,鼠标等消息, 造成所谓的死住!!
    和其他消息比较:如果执行一个消息,没有执行完毕的时候, 新的消息来了, 操作系统尽管会看消息的优先级,但是 操作系统所做的工作是决定下一个消息该谁执行,说白了就是排队。  如果当前消息耗时,也会影响到下一个消息的执行。除了优先级导致执行的顺序外,还会有一个小问题, 有时候操作系统会抛弃wm-timer.比如:有多个定时器, 某个定时器“稍微”耗时,由于到了时间间隔了, 新的wm_timer又来了,此时操作系统继续执行当前的。   后面的大量wm_timer。有的会被抛弃。 不光 时间不准,而且会被抛弃。
      

  12.   


    第一点:是我的代码有误?还是网上的 说法有误,说什么wm_tiemr处理降低cpu,还会延迟或者抛弃看来不可信第二点:
    我先说说我对wm_timer的理解:wm_timer是一种低优先级的消息, 貌似整个windows中,它和wm_paint是最低的, 所以是最后执行这消息!进入case wm_timer的时候, 如果此时执行了 部分代码, 突然 新的消息进入程序的消息队列中(windows并不会去理解执行新的消息),依然继续执行wm_timer里的代码。  如果这代码耗时,那么就会影响到 上面提到的新的消息了, 比如界面,鼠标等消息, 造成所谓的死住!!
    和其他消息比较:如果执行一个消息,没有执行完毕的时候, 新的消息来了, 操作系统尽管会看消息的优先级,但是 操作系统所做的工作是决定下一个消息该谁执行,说白了就是排队。  如果当前消息耗时,也会影响到下一个消息的执行。除了优先级导致执行的顺序外,还会有一个小问题, 有时候操作系统会抛弃wm-timer.比如:有多个定时器, 某个定时器“稍微”耗时,由于到了时间间隔了, 新的wm_timer又来了,此时操作系统继续执行当前的。   后面的大量wm_timer。有的会被抛弃。 不光 时间不准,而且会被抛弃。

    up 起来 
      

  13.   

    定时器就是内核的一个对象,你没添加一个定时器就是在内核里添加了一个对象,这些对象是一类似hash的结构(根据你设置的定时器时间进行hash),没次切换到内核线程的线程的时候都会对这些定时器进行操作,当发现定时器到时间了就启动你所设施的方法。
    大概是这个样子,内核看了一些,有些记不清了。
      

  14.   

    WM_TIMER消息优先级低,会排到消息队列尾部。如果WM_TIMER总是被延迟,那表明了:其它消息太多,或者其它消息处理消耗太长时间。
    前面未被处理的WM_TIMER消息被后来的WM_TIMER消息抛弃,表明:WM_TIMER消息处理太消耗时间了。总而言之,WM_TIMER被延迟或被抛弃,说明:
    要么系统计算开销太大,CPU计算不过来,需要增加计算机的计算能力;
    要么处理消息时阻塞太多浪费了时间(比如SOCKET通讯时用BLOCKING阻塞模式接收数据)。阻塞时CPU不会100%,但程序却无法往下执行,无法处理队列中其它的消息。还有一个要考虑的问题是:丢失或延迟了WM_TIMER消息,程序逻辑是否会产生错误。
    要尽量做到:丢失或延迟WM_TIMER消息,程序依然健壮。
      

  15.   

    用户定时器本身就是 定时器队列,占用的资源很少
    多定义几个定时器,只会在定时器链表中多生成几个节点,然后每个时钟tick需要多查询几个节点是否到期
      

  16.   

    从做软件与硬件的角度上来说,定时器的确消耗CPU计算率,但是定时器相对来说是比较方便的,但是定时器的最大个数应该每台PC都有限制的(我没测试过),而线程隶属于进程,只是时间片的轮转罢了,但是管理好时间片执行顺序是要花点功夫的,所以在定时器使用不多的情况还是使用定时器,CPU允许的,但是比较多了就还是线程吧
      

  17.   


    WM_TIMER消息优先级低,会排到消息队列尾部。如果WM_TIMER总是被延迟,那表明了:其它消息太多,或者其它消息处理消耗太长时间。
    前面未被处理的WM_TIMER消息被后来的WM_TIMER消息抛弃,表明:WM_TIMER消息处理太消耗时间了。
    更正一下: 如果定时器本身耗时,那么wm_timer也会延迟的,  甚至会丢弃。不仅仅是被其他消息耗时导致。wm_timer自身也会
      

  18.   

    定时器可以使用WM_TIMER,也可以不用WM_TIMER 用TimerProc 也可以,二者不同之处,一个会转换为消息,一个直接处理;然而不管如何,定时器的代码要简短,耗时要小,不能有Sleep,Wait类API函数,等会暂停线程(界面线程,往往是主线程),执行的调用。不然就会让消息循环死掉。界面死掉;定时器也不要开死循环,需要死循环的任务,开线程处理。如果需要定时,去处理一个比较耗时的任务,可以开个定时器,定时器到的时候,开个线程处理那个任务。
    然后定时器就可以结束了。
      

  19.   

    sleep尽管会导致线程睡眠,但是依然使用, 原因是,有的线程函数如果不加的话,其他线程很可能导致某个时间里没有机会去执行,所以往往加上:sleep(50); //50ms之类的。只是时间长短的问题。这一点,我不赞同你。第二点:wait类的函数,主线程里使用,你可能忘记了,比如 程序退出的时候,主线程setevetn后,检测子线程句柄,,该线程是否结束,此时用waitforsingleobject等函数。至于其他地方,是不能使用的。但是sleep用在线程里,我觉得没有什么不妥。其还有另一个功能: while(1)
    {Sleep(1000);
    ....
    }起到定时作用。
      

  20.   

    sleep尽管会导致线程睡眠,但是依然使用, 原因是,有的线程函数如果不加的话,其他线程很可能导致某个时间里没有机会去执行,所以往往加上:sleep(50); //50ms之类的。只是时间长短的问题。这一点,我不赞同你。第二点:wait类的函数,主线程里使用,你可能忘记了,比如 程序退出的时候,主线程setevetn后,检测子线程句柄,,该线程是否结束,此时用waitforsingleobject等函数。至于其他地方,是不能使用的。但是sleep用在线程里,我觉得没有什么不妥。其还有另一个功能: while(1)
    {Sleep(1000);
    ....
    }起到定时作用。

    Sleep 最好不要用在主线程里,也不要用在定时器里,界面线程也尽量不要Sleep
    工作者线程,Sleep 没有问题,只看需要不需要。
      

  21.   

    比如 程序退出的时候,主线程setevetn后,检测子线程这种情况,PostMessage(WM_CLOSE)
    就可以了可以开一个线程等待其他所有线程,然后PostMessage(WM_CLOSE)就可以了。除非你的程序,不开窗口,不用界面(或者是个控制台程序)
    否则,主线程(界面线程)里等待,睡眠都不是很好。主要是界面无响应,这种用户体验不是很好。另外谢谢补充!
      

  22.   

    Sleep(1000);
    和定时器的主要区别是,Sleep用于界面线程的话,界面的消息循环立即停止运行定时器,只在时间到的时候,执行一段代码,执行完就会返回,重新执行线程的代码,是一种伪并行执行(一个线程并行执行线程和定时器代码)。
    Sleep是串行化的执行的,只是Sleep那段时间并不执行线程的代码,是不占用CPU的,CPU可以执行别的线程的代码。另外不同优先级的线程,才需要Sleep来让别的线程执行;相同优先级的线程,至少Windows的 Wi32 的代码,是可以自动切换线程的;
    不需要通过Sleep,来让别的线程先执行,以避免线程饿死。
      

  23.   

    你说这一段,是来自那本书,推荐我看看,多谢我看过《win32多线程设计》 没提到过
      

  24.   

    资源消耗,线程肯定比定时器大上万倍。运行效率,wm_timer是消息机制,不能运行的很快,消息机制本身就非常慢,高速大量消息,什么都不做,也会有一定的cpu占用,但是它只占一个线程。
      

  25.   

    你说这一段,是来自那本书,推荐我看看,多谢我看过《win32多线程设计》 没提到过

    这些,有些是书本里提到的,有些是自己总结的,具体哪些是哪本书里的,哪些是自己总结的,还真不是一下子就能够分清楚的。
    不过,一般讲到多线程的书里,不会提到定时器和线程的的区别与联系的,最多提到可等待定时器,因为
    多线程最主要问题,
    1) 解决同步问题,(临界区,事件,互斥量,信号量)以及其他同步函数的使用。 
    2) 全局变量问题,
         2.1)用全局变量,在线程间通讯,
         2.2)全局变量的编译优化问题----会和多线程有一定冲突---可能要使用 volatile关键字,定义  全局变量。
    3)  线程里使用,开辟线程的函数的,局部变量的问题(通过参数传入),函数结束,线程还在运行,变量已经失效了,会产生逻辑错误。 
    4) 线程里,使用开辟线程的函数,分配的内存的问题(通过参数传入),谁来释放内?
        多线程造成的,内存泄露和野指针问题。
        4.1)分配者释放,只有线程结束后,函数才能释放内存,结束运行。
        4.2)使用者释放,线程结束运行前,先释放内存,然后结束运行。
             开辟线程的函数,开线程后立即结束运行。   
    5) MFC,C++,C,C++标准库,C标准库,与多线程的关系,以及解决方案。
    6) 异步IO函数,IO完成例程等与多线程的处理。
    7) 线程池技术。
    8) 多线程的调试方法。
    9) 多线程的策略 ----经典多线程问题,P/V 操作,读者写者问题等,这个好像是操作系统,方面的书籍里提到的。一般书籍,很少提及定时器和多线程的关系。Sleep 很多书籍提到时,并不是用来定时或者同步的,只是用来代替,一段可以运行一段时间的程序的。
    SleepEx 倒是可以用来同步线程的。Sleep 在多线程中,除了可以定时唤醒线程外,作用不大,也就是虚耗时间,不占用CPU而已。
    多线程,自有他的调度机制,相同优先级的线程,不必Sleep,其他线程也可以得到时间片;Sleep以后,其他线程,可以多一点机会运行;
    不Sleep,机会略少一点,并不是没有机会运行的。一般用临界区,事件,互斥量,信号量 等进行同步;
    事件,互斥量,信号量一般和等待函数,释放函数一起使用。PS:
    实际用Sleep 来同步的很少,因为代码运行时间,不是那么好驾驭的。