今天从codeproj上看了段代码,作者自己封装了一个sleeper类。
CSleeper::CSleeper()
{
m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
}CSleeper::~CSleeper()
{
CloseHandle(m_hEvent);
}void CSleeper::Sleep(DWORD dwMilliseconds)
{
WaitForSingleObject(m_hEvent, dwMilliseconds);
}
他这样的目的是什么?这样和直接使用sleep()有什么本质区别吗?难道是为了移植吗?移植的话linux下也没有WaitForSingleObject函数啊?
很费解,欢迎大家进来讨论。

解决方案 »

  1.   

    据我了解,没什么本质区别,都是把线程置于不可调度状态了,都是要转到内核态。这种封装成一个类再利用构造和析构的方法经常看到,主要是为了防止发生异常时候有资源没释放或者有必要代码没执行的。
    这里估计就是防止线程没办法被唤醒。
    比如:
    thread A:
    CSleeper cs
    handle hb = createthread(b, cs)thread B:
    cs.sleep(9999999)这种情况,在使用正常的sleep时,若A在某个地方异常跳出,hb被释放,则B出于长期挂起而不可控状态,此时没办法唤醒B。用个类封装起来的话,A异常,会调用cs的析构函数(无论如何都会调用的),B就被唤醒了。
    当然,可以吧hb保存到更高级别的作用域,但是更高级别的也可能异常!
    呵呵,只是举个极端一点的例子,这么用也是为了方便,比如控制程序退出时的线程退出顺序,可以用下。不知道还有没有什么更高深的用意,暂时就没想到了。
      

  2.   

    哈哈,找到了,分享给大家。
    作者的话:
    The first is the CSleeper class. It's sole purpose in life is to create an event handle that will never be signalled and wait a specified amount of time on that handle. I wrote this class to avoid possible deadlocks. I can't anticipate the kinds of applications that the CLogger class will find itself in. If it's compiled into an application that uses DDE the Sleep() API becomes potentially unsafe. See the MSDN documentation on Sleep(). MSDN中sleep的问题:You have to be careful when using Sleep and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. If you have a thread that uses Sleep with infinite delay, the system will deadlock. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than Sleep.
      

  3.   

    WaitForSingleObject可以提前结束,而sleep则一直等待
      

  4.   

    这个封装不是一个很好的习惯
    因为它每次都会创建一个event, 对于win系统来说, 每个event都会占用一个内核对象(handle)句柄
    也就是说, 大量的class会造成大量的内核对象占用, 大规模应用的情况下, 你的操作系统可能很快就被耗尽内核资源
      

  5.   

    资源消耗应该都差不多,只不过WaitForSingleObject很灵活,不仅仅能实现sleep的效果还可以提前结束sleep状态
      

  6.   

    Sleep的话,只是睡一段时间,时间一到,就变成可调度状态。而WaitForSingleObject则是等待某个内核对象变成有信号状态,其目的和意义很明显,因此更具有针对性。我个人的习惯,在主线程中不用WaitForSingleObject,因为它容易引起死锁。
    楼主引用的那个类,我觉得做精细的理论研究不错,然而并不实用。设想一下,实际中应对一个庞大的工程,每当你定义一个CSleeper对象,就意味着悄悄创建了一个内核对象,而且内核对象在CSleeper对象没有被析构之前一直存在,开销是明显的。严重的情况是,如果在堆上创建了CSleeper对象,而忘记手动删除,且此时这个对象被用于了某种线程的同步,那么一旦出问题将很难调试,因为这个事件内核对象是在幕后的。
      

  7.   

    WaitForSingleObject Sleep其实从两个英文单词的语义你就能看出差别:
    前者等待信号返回, 后则等待一定的时间.用在某个内核对象的等待上,明显前者更灵活,
    因为你等待信号的时间内,信号也可能提前返回了.而后者则需要强制等待固定的时间.