不使用Sleep,如何让线程没任务时不占用CPU资源.

vatajoan 2013-10-09 11:19:44
需求是:线程池中有四个线程,在没有任务的时候,希望线程处于空闲时态,不占用CPU资源,但不能SLEEP,有任务到来时,线程能够立即执行。
当然我知道在一般情况下,空闲时就让线程睡眠,但是线程进入睡眠之后,什么时候再获得CPU控制权是由操作系统决定的,当任务到达时,线程并不能立即唤醒执行,这样的话就算是Sleep(1)毫秒也不能满足要求。
希望大家广泛发言,提供一切想法和意见。
...全文
1668 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
5t4rk 2013-11-18
  • 打赏
  • 举报
回复
引用 15 楼 91program 的回复:
[quote=引用 13 楼 vatajoan 的回复:] 哎,看来没有解决办法呀,EVENT之类的切换内核太费时了。
看来 LZ 只能换真正的实时操作系统了,嘿嘿...[/quote] ++
sheds 2013-11-15
  • 打赏
  • 举报
回复
楼主给导弹写程序吗?别用window了
「已注销」 2013-11-11
  • 打赏
  • 举报
回复
引用 3 楼 vatajoan 的回复:
信号号和事件之类的更不能满足要求,因为线程会进入内核模式,效率更低
操作系统调度你的4个线程,不用进入内核态吗? 你的4个线程生活在操作系统不理解的地方吗?
mc_ran 2013-11-06
  • 打赏
  • 举报
回复
用信号量,然后再用一个互斥变量可以写一个 类似 linux下 的 pthread_cond_t 的东西,很好用的,我现在有一份,线程没事做的时候就 sleep, 有任务了,负责调度的线程就broadcost 一下就行了
版主大哥 2013-11-05
  • 打赏
  • 举报
回复
引用 13 楼 vatajoan 的回复:
哎,看来没有解决办法呀,EVENT之类的切换内核太费时了。
好像楼主很牛... 请问有测试过费多少时间呢?分钟级别?秒级别?毫秒级别?
vatajoan 2013-11-05
  • 打赏
  • 举报
回复
还有其他办法吗
爆豆 2013-10-22
  • 打赏
  • 举报
回复
up!
lm_whales 2013-10-22
  • 打赏
  • 举报
回复
SleepEx
zhouzhipen 2013-10-16
  • 打赏
  • 举报
回复
不进入内核就只有用纤程了,自己调度。 不过如果线程事件等待进入内核都嫌费时的话,就不要做Windows程序开发了。
yaozhiyong110 2013-10-16
  • 打赏
  • 举报
回复
你自己挂起和唤醒线程就是了撒...
leechiyang 2013-10-16
  • 打赏
  • 举报
回复
楼上的代码不符合楼主的要求啊。
引用 12 楼 flydreamGG 的回复:
要看你的任务性质了,如果是针对WINDOWS的I/O操作,有个异步完成端口,可以参考《windows核心编程》。 如果不是I/O操作,那么有任务和没任务就需要你自己来判断了,最典型的就是waitfor+event的模式,你要是嫌内核切换费时,那也没办法
正解
欢乐马_19e9 2013-10-16
  • 打赏
  • 举报
回复
给你分享一下我的类库把,https://code.csdn.net/kingsollyu/libx 这里有。
		//=========================================================================
		// 函数名称: SuperSleep
		// 函数?明: void  高精度延时,cpu占用低,窗口不卡死,一次最大可延时几年 
		//=========================================================================
		// 参    数: __in int nTime			1000微秒 = 1毫秒 ; 1000毫秒 = 1秒
		// 参    数: __in int nSpeed		可空:毫秒  0 毫秒  1 微秒  2 秒  3 分  4 小时  5 天
		//=========================================================================
		static void SuperSleep(__in int nTime,__in int nSpeed = 0);

		//=========================================================================
		// 函数名称: ProcessEvent
		// 函数?明: void 暂时转让控制权,以便让 Windows 操作系统有机会处理其它的如用户键盘或鼠标输入等事件。
		//				 直到操作系统处理并发送完程序队列中的所有事件后,命令才会返回。
		//=========================================================================
		static void ProcessEvent();

void CLibX::System::SuperSleep( __in int nTime,__in int nSpeed /*= 0*/ )
{
	LARGE_INTEGER lar;
	if (nSpeed == 0) nSpeed = 1;
	else if (nSpeed == 1) nSpeed = -10;
	else if (nSpeed == 2) nSpeed = 1000;
	else if (nSpeed == 3) nSpeed = 1000 * 60; 
	else if (nSpeed == 4) nSpeed = 1000 * 60 * 60; 
	else if (nSpeed == 5) nSpeed = 1000 * 60 * 60 * 24; 

	lar.QuadPart = -10 * nTime * nSpeed * 1000 ;
	HANDLE hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
	SetWaitableTimer(hTimer,&lar,NULL,NULL,NULL,FALSE);
	while (MsgWaitForMultipleObjects(1,&hTimer,FALSE,INFINITE,QS_ALLINPUT) != WAIT_OBJECT_0)
	{
		CLibX::System::ProcessEvent();
	}

	CloseHandle(hTimer);
}

void CLibX::System::ProcessEvent()
{
	MSG msg;
	while(PeekMessage(&msg,NULL,NULL,NULL,1) != 0)
	{
		DispatchMessage(&msg);
		TranslateMessage(&msg);
	}
}
davidyu720 2013-10-15
  • 打赏
  • 举报
回复
引用 13 楼 vatajoan 的回复:
哎,看来没有解决办法呀,EVENT之类的切换内核太费时了。
系统每秒发生上千次切换,多你一次两次又何妨? 如果实在是在意内核切换耗时,干脆用纯DOS编写程序吧。无所谓用户态核心态了,随心所欲。
horris 2013-10-14
  • 打赏
  • 举报
回复
引用 3 楼 vatajoan 的回复:
信号号和事件之类的更不能满足要求,因为线程会进入内核模式,效率更低
没听说信号量和事件效率低的,如果你不用I/O完成端口(那个比较复杂),事件是效率最高的了
昨夜无风 2013-10-14
  • 打赏
  • 举报
回复
引用 15 楼 91program 的回复:
[quote=引用 13 楼 vatajoan 的回复:] 哎,看来没有解决办法呀,EVENT之类的切换内核太费时了。
看来 LZ 只能换真正的实时操作系统了,嘿嘿...[/quote] LS,膜拜了,你咋弄那么多牌牌,嵌入式的牛人
91program 2013-10-14
  • 打赏
  • 举报
回复
引用 13 楼 vatajoan 的回复:
哎,看来没有解决办法呀,EVENT之类的切换内核太费时了。
看来 LZ 只能换真正的实时操作系统了,嘿嘿...
jackson35296 2013-10-14
  • 打赏
  • 举报
回复
创建一个event,WaitForSingleObject等待这个event,需要立即执行的时候,只需要SetEvent
昨夜无风 2013-10-10
  • 打赏
  • 举报
回复
要看你的任务性质了,如果是针对WINDOWS的I/O操作,有个异步完成端口,可以参考《windows核心编程》。 如果不是I/O操作,那么有任务和没任务就需要你自己来判断了,最典型的就是waitfor+event的模式,你要是嫌内核切换费时,那也没办法
足球中国 2013-10-10
  • 打赏
  • 举报
回复
引用 10 楼 dixh1989 的回复:
既然你有4个线程,你可以单独创建一个线程来唤醒这4个吧~不用时先关了?
就是。要求这么高为什么不关了。用的时候再开。
是_这样吗 2013-10-10
  • 打赏
  • 举报
回复
既然你有4个线程,你可以单独创建一个线程来唤醒这4个吧~不用时先关了?
加载更多回复(10)

15,474

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧