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

Windows线程(五)关键段无法解决线程同步问题

程序员文章站 2022-05-04 17:09:48
...

关键段:


关键段类型CRITICAL_SECTION

1.初始化关键段:
void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
2.销毁关键段:
void DeleleCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
3.进入关键段:
void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
4.离开关键段:
void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

关键段解决线程互斥问题测试代码如下:

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

#define THREAD_NUM 10

CRITICAL_SECTION g_csThreadParameter;
CRITICAL_SECTION g_csThreadCode;

unsigned long g_nNum;

unsigned int __stdcall ThreadFun(void *pM)
{
    int nThreadNum = *(int *)pM;

    //离开子线程的关键区域
    LeaveCriticalSection(&g_csThreadParameter);
    Sleep(50);

    //进入子线程互斥区域
    EnterCriticalSection(&g_csThreadCode);
    g_nNum++;

    Sleep(0);

    printf("线程编号为%d, 全局资源值为%d\n", nThreadNum, g_nNum);

    //离开各自线程互斥区域
    LeaveCriticalSection(&g_csThreadCode);

    return 0;
}

int main(int argc, char *argv[])
{
    HANDLE handle[THREAD_NUM];
    int i = 0;

    printf("--------------------经典线程同步:关键段--------------------\n");


    //初始化关键段
    InitializeCriticalSection(&g_csThreadParameter);
    InitializeCriticalSection(&g_csThreadCode);

    g_nNum = 0;

    while(i < THREAD_NUM)
    {
        //进入子线程关键段区域
        EnterCriticalSection(&g_csThreadParameter);
        handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, &i, 0, NULL);
        ++i;
    }

    WaitForMultipleObjects(THREAD_NUM, handle, 1, INFINITE);

    //删除关键段
    DeleteCriticalSection(&g_csThreadCode);
    DeleteCriticalSection(&g_csThreadParameter);

    system("pause");

    return 0;
}

以上代码在Visual Studio 2010中的5次运行结果如下:


Windows线程(五)关键段无法解决线程同步问题


Windows线程(五)关键段无法解决线程同步问题


Windows线程(五)关键段无法解决线程同步问题


Windows线程(五)关键段无法解决线程同步问题


Windows线程(五)关键段无法解决线程同步问题


如上图所示,该段使用关键段的测试代码的确解决了线程互斥的问题,但是并没有解决线程同步的问题,因此我们需要其他方法,解决线程同步问题。