Windows 线程(十二) 临界区及线程函数中使用静态变量
一个例子
我们首先看这么一段代码
#include <Windows.h>
#include <process.h>
volatile INT g_nNum;
volatile INT g_nLoopCount = 100;
CRITICAL_SECTION g_Cs; // 临界区/关键段
UINT WINAPI ThreadFunc(LPVOID lParam)
{
static INT nThreadIndex = 0;
EnterCriticalSection(&g_Cs);
++nThreadIndex;
g_nNum = 0;
for (INT i = 0; i < g_nLoopCount; ++i)
{
g_nNum += i;
}
_tprintf(TEXT("Thread[%d]:[%d]\n"), nThreadIndex, g_nNum);
LeaveCriticalSection(&g_Cs);
return 0;
}
int main()
{
CONST INT MAXTHREADCOUNT = 10;
HANDLE hThreads[MAXTHREADCOUNT] = { INVALID_HANDLE_VALUE };
InitializeCriticalSection(&g_Cs);
for (INT i = 0; i < MAXTHREADCOUNT; ++i)
{
hThreads[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, NULL);
}
WaitForMutipleObjects(MAXTHREADCOUNT, hThreads, TRUE, INFINITE);
for (INT i = 0; i < MAXTHREADCOUNT; ++i)
{
CloseHandle(hThreads[i]);
}
DeleteCriticalSection(&g_Cs);
}临界区
CRITICAL_SECTION
这个就是临界区, 也称之为关键段
- 它是一个结构体
- 微软并没有提供文档
- 我们只要会用就行了
InitializeCriticalSection
初始化临界区
它会分配一些内存
- 我们无法操作这块内存
- 它是分配的与临界区相关的内存
- 绑定临界区和内存
- 清零临界区
- 清零关联的内存
- 无返回值, 如果分配失败会抛出异常
InitializeCriticalSectionAndSpinCount
以旋转锁的方式使用临界区
- 也是对临界区的初始化
- 有返回值, 分配失败会返回FALSE
- 不会抛出异常
参数2 是重试的次数
- 设置在重试多少次后, 才使线程进入
不可调度状态 - 参数设置唯一后, 就没有了
旋转锁的特性了
- 设置在重试多少次后, 才使线程进入
DeleteCriticalSection
删除临界区
EnterCriticalSection
进入临界区
- 使线程
获准访问 - 使无法访问的线程进入
不可调度状态
TryEnterCriticalSection
尝试进入临界区
- 如果能进入, 则
获准访问 - 如果不能进入, 线程
不会进入不可调度状态 - 也不会执行关键段的代码
LeaveCriticalSection
离开临界区
线程中使用静态变量
例子中我们可以看到, 为了标识线程, 使用了一个 static 的变量
- 静态变量存在于静态区
- 它相当于是全局变量, 但是作用域仅限
线程函数 - 它只会被初始化一次
在某些时候, 推荐使用静态变量替代全局变量
- 因为它有作用域
- 也要注意对静态变量的
原子操作
未完待续...
如有错误,请提出指正!谢谢.
本文由 花心胡萝卜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2017-06-26 at 02:10 pm