windows内核线程同步轮询方式以及旋转锁


在windows内核中,有一种线程同步技术--轮询。请看下面一段代码:

   
  volatile BOOL g_fFinishedCalculation = FALSE;//共享变量
  

//主线程不断测试变量g_fFinishedCalculation
int WINAPI _tmain()
{
CreateThread(....,RecalcFunc,...);
while(!g_fFinishedCalculation)
;
...
}

DWORD WINAPI RecalcFunc(PVOID pvParam)
{
//执行计算
...
g_fFinishedCalculation = true;

return 0;
}

主线程不断测试变量的值,实现直到函数RecalcFunc执行完毕之后才继续执行。

我们可以发现,代码中的共享变量前面有一个关键字volatile。为什么需要这个关键字呢?

还有,请看下列旋转锁的代码:

   
  BOOL g_fResourceInUse = FALSE;
  
void Func1()
{
//等待访问资源
while(InterlockedExchange(&g_fResourceInUse,TRUE) == TRUE)
Sleep(0);

//访问资源
...

//不再需要访问资源
InterlockedExchange(&g_fResourceInUse,FALSE);
}

这里的关键字为什么不在volatile也是可以的呢?
求解~

内核 C++

HKG字幕组 12 years, 11 months ago

①一个定义为volatile的变量是说这变量可能会被意想不到地改变,例如操作系统、硬件、并发的线程、进程等改变,所以每次访问这个变量时都要从内存中对应地址取出。换句话说,这个关键字通知编译器不要对该变量的访问进行优化,如果不加编译器会对变量进行优化,将变量拷贝到cpu的寄存器(这个工作有编译器完成,只做一次)中,因为毕竟寄存器的访问比内存访问快得多,一般情况下这样做是有利的,但是对于多线程机制来说,这样就无法捕捉到其他用户对变量的修改了。
②这类变量的适用情况:
1) 并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量

train answered 12 years, 11 months ago

Your Answer