今天从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函数啊?
很费解,欢迎大家进来讨论。
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函数啊?
很费解,欢迎大家进来讨论。
解决方案 »
- 窗口显示顺序//改变mainfame窗口显示的顺序为第二位
- VS08环境下如何给button加图片!
- 如何切换单个窗格内的视图?
- 怎么监视用户从Explorer中的拖拽(Drag and Drop)操作
- 1998离我们有多远!
- 绘图程序的问题?
- 问:为什么有时候CDC的对象建立时用CreateDC,而有时候用CreateCompatibleDC?两者有什么不同?
- 老师说在数据库设计时,要设好数据库接口给应用程序, 请问数据库接口包括点什么东西?
- ADO技术、SQL实战过程中的连接错误。
- 求熟悉路径填充的VC程序员代写小程序(几百行),费用可观,请有意者联系QQ 317419289注明VC代写
- 为什么VC++6.0的FileView里老是出现External Dependencies文件夹
- 为什么我实现的一个SMTP发送邮件没有内容?
这里估计就是防止线程没办法被唤醒。
比如:
thread A:
CSleeper cs
handle hb = createthread(b, cs)thread B:
cs.sleep(9999999)这种情况,在使用正常的sleep时,若A在某个地方异常跳出,hb被释放,则B出于长期挂起而不可控状态,此时没办法唤醒B。用个类封装起来的话,A异常,会调用cs的析构函数(无论如何都会调用的),B就被唤醒了。
当然,可以吧hb保存到更高级别的作用域,但是更高级别的也可能异常!
呵呵,只是举个极端一点的例子,这么用也是为了方便,比如控制程序退出时的线程退出顺序,可以用下。不知道还有没有什么更高深的用意,暂时就没想到了。
作者的话:
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.
因为它每次都会创建一个event, 对于win系统来说, 每个event都会占用一个内核对象(handle)句柄
也就是说, 大量的class会造成大量的内核对象占用, 大规模应用的情况下, 你的操作系统可能很快就被耗尽内核资源
楼主引用的那个类,我觉得做精细的理论研究不错,然而并不实用。设想一下,实际中应对一个庞大的工程,每当你定义一个CSleeper对象,就意味着悄悄创建了一个内核对象,而且内核对象在CSleeper对象没有被析构之前一直存在,开销是明显的。严重的情况是,如果在堆上创建了CSleeper对象,而忘记手动删除,且此时这个对象被用于了某种线程的同步,那么一旦出问题将很难调试,因为这个事件内核对象是在幕后的。
前者等待信号返回, 后则等待一定的时间.用在某个内核对象的等待上,明显前者更灵活,
因为你等待信号的时间内,信号也可能提前返回了.而后者则需要强制等待固定的时间.