一. 线程安全问题
多线程同时访问全局变量:一个线程取值后失去CPU另一个线程取值后也失去CPU,此时它们保存的就是相同的值。也是是说,比如两个线程再次对全区变量做++操作时变量只会被修改为同样的值。
二. 临界区(线程锁)
一. 临界区
临界区:Critical Section (Critical:临界的、关键的)
1、创建CRITICAL_SECTION:
CRITICAL_SECTION cs;
2、在使用前进行初始化
InitializeCriticalSection(&cs);
3、在函数中使用:
DWORD WINAPI 线程A(PVOID pvParam) {
EnterCriticalSection(&cs);
//对全局遍历X的操作
LeaveCriticalSection(&cs);
return(0);
}
DWORD WINAPI 线程B(PVOID pvParam) {
EnterCriticalSection(&g_cs);
//对全局遍历X的操作
LeaveCriticalSection(&g_cs);
return(0);
}
4、删除CRITICAL_SECTION
VOID DeleteCriticalSection(PCRITICAL_SECTION pcs);
临界区结构体:
typedef struct _RTL_CRITICAL_SECTION {
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
LONG LockCount;
LONG RecursionCount;
HANDLE OwningThread;
HANDLE LockSemaphore;
DWORD SpinCount;
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
LockCount:
它被初始化为数值 -1
此数值等于或大于 0 时,表示此临界区被占用
等待获得临界区的线程数:LockCount - (RecursionCount -1)
RecursionCount:
此字段包含所有者线程已经获得该临界区的次数
OwningThread:
此字段包含当前占用此临界区的线程的线程标识符
此线程 ID 与GetCurrentThreadId 所返回的 ID 相同
注意:
1. 只对可能产生安全问题的最小单元进行加锁,否则会降低运行效率。
2. 一般有几个资源就定义几把锁。