Sleep(0)和SwitchToThread之间的区别有关问题
Sleep(0)和SwitchToThread之间的区别问题
两个都是放弃时间片,按照书中或者网上的一般说法,Sleep(0)将会在可调度的同等级或者高优先级的线程里面找,而SwitchToThread则是全系统范围,低优先级的也可能会被调用。
那么我为了测试spinlock而写了这么一段代码
意思就是说主线程的优先级高,辅助线程的优先级低,辅助线程用来翻牌,主线程一直等待这个牌。
刚开始的时候没有Sleep或者SwitchToThread,那么主线程等待翻牌的动作大概延迟5秒所有,这个说得通,因为高优先级的线程一直占用CPU导致辅助线程不能翻牌直到OS为了防止线程饿死而动态提升了它的优先级。
然后我就修改了一下代码加了一个Sleep(0)。
按照我的理解,Sleep(0)只会调入优先级大于等于主线程的其它线程,而辅助线程的优先级低,那么应该来说根本就轮不到调用它,从而加不加Sleep(0)对性能的影响应该不大,可是测试结果出乎我的意料,加了Sleep(0)后辅助线程基本上马上就翻牌,从而主线程得以退出。
这是为什么?难道说现在Sleep(0)也调度低等级线程了么?
测试环境:Win 7 32 bit
工具: VS 2010
------解决方案--------------------
优先级不是固定的,得到调度会降低,得不到调度会提高,以保证低优先级的线程不会挂起.
------解决方案--------------------
windows是按时间和优先级混合的调试方式,在用户层没有显式的可以调整线程调试顺序的接口。所有这些都是系统完成的,应用程序员能做的就是调整优先级和放弃当前时间片。
------解决方案--------------------
假设有线程a,b
a的优先级高于b
1.a{
sleep(0);
//这是OS就回去调度system中的thread,由于(比较system中可以调度thread的priority)a的优先级高于b,所以a就被启用
}
2.a{
SwitchToThread(void);
//这是OS就回去调度system中的thread,由于SwitchToThread允许优先级较低的线程运行,所以b就被启用
}
------解决方案--------------------
Sleep(0):时间片只能让给优先级相同或更高的线程;
SwitchToThread():只要有可调度线程,即便优先级较低,也会让其调度。
两个都是放弃时间片,按照书中或者网上的一般说法,Sleep(0)将会在可调度的同等级或者高优先级的线程里面找,而SwitchToThread则是全系统范围,低优先级的也可能会被调用。
那么我为了测试spinlock而写了这么一段代码
- C/C++ code
volatile LONG g_x = FALSE; unsigned int _stdcall Thread_Low(void* pParam) { InterlockedExchange(&g_x,TRUE); return 0; } void main() { HANDLE hThread = (HANDLE)_beginthreadex(NULL,NULL,Thread_Low,NULL,CREATE_SUSPENDED,NULL); _ASSERT(SetThreadPriority(hThread,THREAD_PRIORITY_IDLE)); SetThreadAffinityMask(hThread,0x00000001); _ASSERT(SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST)); SetThreadAffinityMask(GetCurrentThread(),0x00000001); ResumeThread(hThread); CloseHandle(hThread); LARGE_INTEGER liFreq = {0}; LARGE_INTEGER liStart = {0}; LARGE_INTEGER liEnd = {0}; QueryPerformanceFrequency(&liFreq); QueryPerformanceCounter(&liStart); while(InterlockedExchange(&g_x,FALSE) == FALSE) Sleep(0); QueryPerformanceCounter(&liEnd); cout<<(liEnd.QuadPart - liStart.QuadPart) / (double)liFreq.QuadPart<<'s'<<endl; return; }
意思就是说主线程的优先级高,辅助线程的优先级低,辅助线程用来翻牌,主线程一直等待这个牌。
刚开始的时候没有Sleep或者SwitchToThread,那么主线程等待翻牌的动作大概延迟5秒所有,这个说得通,因为高优先级的线程一直占用CPU导致辅助线程不能翻牌直到OS为了防止线程饿死而动态提升了它的优先级。
然后我就修改了一下代码加了一个Sleep(0)。
按照我的理解,Sleep(0)只会调入优先级大于等于主线程的其它线程,而辅助线程的优先级低,那么应该来说根本就轮不到调用它,从而加不加Sleep(0)对性能的影响应该不大,可是测试结果出乎我的意料,加了Sleep(0)后辅助线程基本上马上就翻牌,从而主线程得以退出。
这是为什么?难道说现在Sleep(0)也调度低等级线程了么?
测试环境:Win 7 32 bit
工具: VS 2010
------解决方案--------------------
优先级不是固定的,得到调度会降低,得不到调度会提高,以保证低优先级的线程不会挂起.
------解决方案--------------------
windows是按时间和优先级混合的调试方式,在用户层没有显式的可以调整线程调试顺序的接口。所有这些都是系统完成的,应用程序员能做的就是调整优先级和放弃当前时间片。
------解决方案--------------------
假设有线程a,b
a的优先级高于b
1.a{
sleep(0);
//这是OS就回去调度system中的thread,由于(比较system中可以调度thread的priority)a的优先级高于b,所以a就被启用
}
2.a{
SwitchToThread(void);
//这是OS就回去调度system中的thread,由于SwitchToThread允许优先级较低的线程运行,所以b就被启用
}
------解决方案--------------------
Sleep(0):时间片只能让给优先级相同或更高的线程;
SwitchToThread():只要有可调度线程,即便优先级较低,也会让其调度。