Sleep(n)的作用是让当前线程睡眠n毫秒,以便执行其他线程,如果没有其他线程,那睡眠n毫秒后,继续执行。
而如果n=0,Sleep(0)是指CPU交出当前线程的执行权,让CPU去执行其他线程。也就是放弃当前线程的时间片,转而执行其他线程。
那么,Sleep(0)应该在那种情况下使用? 一般来说,如果当前线程比较耗时比较占CPU资源,可以在结尾处加上Sleep(0), 这样效率会得到大大的提高。
另外,还可以用这种方法来保证线程同步,线城池工作时,主线程使用Sleep(0)来等待线程池里所有的线程都完成运行。当线程池线程非常多的时候,这种方法确实是一种非常有效的节省cpu的方式,因为它节省了在线程里使用内核来进行同步的开销。
- void SetCopyFile(short progress)
- {
- if(progress != 100 && m_t1)
- m_t1 = FALSE;
- if(m_CopyPro + m_span <= progress || 100 == progress)
- {
- if(100 == progress && m_t1)
- return;
- ::PostMessage(m_pcHiddenWnd->m_hWnd , WM_CCOPYPROGRESS, progress, 0);
- m_CopyPro = progress;
- Sleep(0);
- }
- }
如上代码,由于该代码处于一个多线程运行的环境中,而拷贝progress又是不停的进行,不断地调用PostMessage()函数,同时还要做消息映射,执行消息相应函数等等,因此这是一个比较耗时的过程,此时,sleep(0)就派上用场了,加在后面,让其他线程也能及时得到运行。
以前在同一个进程里,特别钟爱用Sleep(0)来做一些情况下的线程同步。譬如当线城池工作时,主线程使用Sleep(0)来等待线程池里所有的线程都 完成运行。当线程池线程非常多的时候,这种方法确实是一种非常有效的节省cpu的方式,因为它节省了在线程里使用内核来进行同步的开销。而且很重要的,它 运作的很好,可以说完全在我的控制之内。
然而在我换上了双核cpu后,问题出来了:Sleep(0)经常会比预期中更早返回。当初的设计代码根本没有考虑过多核/多cpu方式下的线程调度。
看来,速度和方便,还是难以两全其美。如果数据对同步敏感,还是不能偷工减料。
另外,在测试中发现非常奇怪的一点: 当线程池工作的时候,在任务管理器里设定该进程只能在一个cpu上运行的时候,该进城所占用的内存量急剧持续增长。而再设回允许在双核下调度时,内存量又开始缓慢持续减少^_^