欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

windows API(9)线程安全 临界区

程序员文章站 2022-03-05 09:55:23
...

线程安全问题

每一个线程都有自己的栈区,而局部变量是存储在栈中的,这就意味着每个线程都有一份自己的局部变量,如果线程仅仅使用“局部变量”则不存在线程安全问题。

但是,如果使用全局变量就会存在线程安全问题。

解决方法-临界区

我们将全局变量称为临界资源,就是一次只允许一个线程进行使用。
访问临界资源的代码就称为临界区。

原理:我们对临界资源增加令牌,只有当令牌为1时代码才可以对临界区进行访问,同时将令牌置0。其它线程便无法访问该临界资源

临界区实现之线程锁:
  1. 创建全局变量 CRITICAL_SECTION cs
  2. 初始化全局变量 InitializeCriticalSection(&cs)
  3. 实现临界区
    EnterCriticalSection(&cs);
    //使用临界资源
    LeaveCriticalSection(&cs);

注意:所有关于逻辑判断的代码都要放在临界区之内

实例
int dwTickets = 10;
//给全局变量加锁
CRITICAL_SECTION cs;

DWORD WINAPI ThreadProc(LPVOID lpParament)
{
    //创建临界区
    EnterCriticalSection(&cs);
    //判断是否还有票
    while (dwTickets > 0)
    {
        printf("还有多少张票%d\n", dwTickets);
        --dwTickets;
        printf("还剩多少张票%d\n", dwTickets);
    }
    LeaveCriticalSection(&cs);
    return 0;
}

int main(int argc, char* argv[])
{
    HANDLE harrThread[2];
    DWORD dwResult1;
    DWORD dwResult2;
    
    //初始化全局变量
    InitializeCriticalSection(&cs);
    harrThread[0] = CreateThread(NULL, 0, ThreadProc, NULL, NULL, NULL);
    harrThread[1] = CreateThread(NULL, 0, ThreadProc, NULL, NULL, NULL);
    
    //在线程全部执行完毕后,才会接着执行下面的内容
    WaitForMultipleObjects(2, harrThread, TRUE, INFINITE);
    printf("线程执行完毕\n");
    CloseHandle(harrThread[0]);
    CloseHandle(harrThread[1]);
    return 0;
}
相关标签: windows API

上一篇: redis-阻塞

下一篇: 安装elasticsearch