Win32开发6-线程2

线程不安全

多个线程操作同一个变量,会有线程不安全的问题,程序示例

#include <Windows.h>
#include <stdio.h>

int gNum = 0;

DWORD WINAPI testProc(LPVOID pParam)
{
    for (int i = 0; i < 10000; i++)
    {
        gNum++; //这样操作线程不安全
    }
    return 0;
}

int main()
{
    DWORD nId = 0;
    HANDLE hThreads[2];
    hThreads[0] = CreateThread(NULL, 0, testProc, NULL, 0, &nId);   //直接启动
    hThreads[1] = CreateThread(NULL, 0, testProc, NULL, 0, &nId);   //直接启动
    WaitForMultipleObjects(2, hThreads, true, INFINITE);
    printf("num = %d\n", gNum);
    
    return 0;
}

说明:

  • 输出结果19812,不是20000,这是线程不安全造成的.
  • 如果输出结果为20000,就把循环次数加大,就会出现错误结果.

线程的原子锁

原子锁可以解决不同线程使用同一个变量的线程安全问题.程序示例.

#include <Windows.h>
#include <stdio.h>

int gNum = 0;

DWORD WINAPI testProc(LPVOID pParam)
{
    for (int i = 0; i < 10000; i++)
    {
        //gNum++; //这样操作线程不安全
        InterlockedIncrement((long*)&gNum);    //线程安全方式
    }
    return 0;
}

int main()
{
    DWORD nId = 0;
    HANDLE hThreads[2];
    hThreads[0] = CreateThread(NULL, 0, testProc, NULL, 0, &nId);   //直接启动
    hThreads[1] = CreateThread(NULL, 0, testProc, NULL, 0, &nId);   //直接启动
    WaitForMultipleObjects(2, hThreads, true, INFINITE);
    printf("num = %d\n", gNum);
    
    return 0;
}

说明:

  • 原子锁执行效率很高.
  • 只支持运算相关的操作,有一定的局限性.
  • 针对不同运算,提供不的函数.

线程互斥

程序示例

#include <Windows.h>
#include <stdio.h>

HANDLE gMutex;

DWORD WINAPI testProc(LPVOID pParam)
{
    char* pChar = (char*)pParam;
    while (true)
    {
        WaitForSingleObject(gMutex, INFINITE);  //使用互斥量来保证线程安全
        for (int i = 0; i < strlen(pChar); i++)
        {
            printf("%c", pChar[i]);
            Sleep(100);
        }
        printf("\n"); 
        ReleaseMutex(gMutex);
    }   
}

int main()
{
    gMutex = CreateMutex(NULL, false, NULL);
    DWORD nId = 0;
    HANDLE hThreads[2];
    const char* pChar = "********";
    hThreads[0] = CreateThread(NULL, 0, testProc, const_cast<char*>(pChar), 0, &nId);   //直接启动
    pChar = "--------";
    hThreads[1] = CreateThread(NULL, 0, testProc, const_cast<char*>(pChar), 0, &nId);   //直接启动
    
    getchar();
    CloseHandle(gMutex);
    return 0;
}

说明

  • 通过原子锁和互斥量的方式来保证线程安全,都是互斥的方式.
  • 针对运算符的互斥,原子量的效率高.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值