zoukankan      html  css  js  c++  java
  • 为什么要对多线程进行加锁操作呢

    一.如果不加锁,会怎么样?

    可能会发生数据竞争,造成数据错乱.

    例子:

    本来想要的结果n=0,但是执行发现n的值不为0,而且有多种取值.究其原因,是因为多个线程之间会发生数据竞争,导致CPU线程调度时出现问题,不能够保证线程内执行代码的原子操作.我发现string str = "hello";这一句是必要的,不然它就不会出现n不为0的现象.(有待进一步研究)

    注意,如果要所有子线程执行完毕后,再执行主线程.要有WaitForMultipleObjects操作.

    #include "windows.h"
    #include <iostream>using namespace std;const int ThreadNum = 50;
    int g_Num = 0;
    DWORD WINAPI ThreadFun(void * param)
    {
        for (int i = 0; i < 100; i++)
        {
            g_Num = g_Num+1;
            string str = "hello";
            g_Num = g_Num-1;
        }
        return 0;
    }
    int main()
    {
        DWORD lpThread[ThreadNum];
        HANDLE h[ThreadNum];
        for (int i = 0; i <ThreadNum; i++)
        {
             h[i] = CreateThread(NULL, 0, ThreadFun, NULL, 0, &lpThread[i]);
        }
        WaitForMultipleObjects(ThreadNum, h, TRUE, INFINITE); //等待所有的子线程执行完毕.
        int n = g_Num;
        cout << "n:" << n << endl;
        return 0;
    }

    二.加锁后的情形

    WaitForMultipleObjects是必须的,一开始忘记了使用这个,导致在EnterCriticalSection处报错,猜测是主线程没有等子线程执行完毕就结束了程序.为了验证猜想,将WaitForMultipleObjects注释掉,
    在子函数中打印,发现确实是这个原因.
    加锁后每次n打印出来的都是0了.
    #include "windows.h"
    #include <iostream>
    using namespace std;
    const int ThreadNum = 50;
    
    CRITICAL_SECTION g_Cs;
    int g_Num = 0;
    DWORD WINAPI ThreadFun(void * param)
    {
        for (int i = 0; i < 100; i++)
        {
            EnterCriticalSection(&g_Cs);
            g_Num = g_Num+1;
            string str = "hello";
            g_Num = g_Num-1;
            LeaveCriticalSection(&g_Cs);
        }
        return 0;
    }
    
    int main()
    {
        InitializeCriticalSection(&g_Cs);
        DWORD lpThread[ThreadNum];
        HANDLE h[ThreadNum];
        for (int i = 0; i <ThreadNum; i++)
        {
            h[i] = CreateThread(NULL, 0, ThreadFun, NULL, 0, &lpThread[i]);
        }
        WaitForMultipleObjects(ThreadNum, h, TRUE, INFINITE); //等待所有的子线程执行完毕.
        int n = g_Num;
        cout << "n:" << n << endl;
        DeleteCriticalSection(&g_Cs);
        return 0;
    }
    新战场:https://blog.csdn.net/Stephen___Qin
  • 相关阅读:
    递归和消去递归
    Time complexity analysis of algorithms
    algorithms中计算时间的渐近表示
    OAuth认证协议原理分析及同步消息到Twitter和Facebook使用方法
    javascript实现URL编码与解码
    before伪类的超有用应用技巧——水平菜单竖线分隔符
    在线工具(转)
    程序员小抄大全
    Web设计的速查卡(转)
    一个简单的AJAX示例(转)
  • 原文地址:https://www.cnblogs.com/Stephen-Qin/p/12702487.html
Copyright © 2011-2022 走看看