Windows临界区简单实现

来源:互联网 发布:其皆出于此乎的其意思 编辑:程序博客网 时间:2024/05/29 18:21

最近看的书中介绍了线程临界区同步方式,思考之前写过的内存释放相关结构便动手实现一个简易的临界区(支持多个线程同时使用)。

关于结构设计的几点介绍:
1.设计采用了先进先出概念,当第一个线程进入临界区后,别的线程需要在临界区等待,临界区释放后下一个线程才能进入临界区;
2.设计采用了递增进入方式,比如第一个线程为0顺序,第二个线程为1顺序等等以此类推;
3.设计采用了轻量级参数,结构安全性比较高,不会出现崩溃情况(按正常临界区方式操作,每次线程退出前需要释放临界区,防止造成死锁)。

函数定义如下:

void TestInitializeCriticalSection(pTestCritical obj);/* 初始化函数实际用处不大稳定考虑在构造函数已经初始化,可以不用 */void TestEnterCriticalSection(pTestCritical obj);//加载临界区void TestLeaveCriticalSection(pTestCritical obj);//释放临界区typedef struct TestCritical//临界区结构体{    TestCritical():nCritical(0),nCount(0)    {    }    volatile int nCritical;/* 临界区运行标志 ,0表示没有进入临界区 ,1 表示进入临界区 */    volatile int nCount;/* 临界区等待进入的顺序计数 */}*pTestCritical;

代码实现如下:

void TestInitializeCriticalSection(pTestCritical obj)/* 初始化函数实际用处不大稳定考虑在构造函数已经初始化,可以不用 */{    while (1 == obj->nCritical) /* 如果临界区已经运行那么初始化失败 */        return ;    obj->nCritical = 0;}void TestEnterCriticalSection(pTestCritical obj)//加载临界区{    int nCount = obj->nCount;/*获取到等待顺序,如果为0为第一个等待进入临界区*/    obj->nCount++;//这里说明下多个线程情况下可能会造成nCount增加慢了一步,不过没有影响 数据一切正常    while (0 != obj->nCritical || (0 != nCount && nCount != obj->nCount))        ;    obj->nCritical = 1;}void TestLeaveCriticalSection(pTestCritical obj)//释放临界区{    if (0 == obj->nCritical)    {        return;    }    obj->nCritical = 0;    obj->nCount--;}

使用方式(测试方法):

    AfxBeginThread(TestCriticalThread,this);    AfxBeginThread(TestCriticalThread2,this);    AfxBeginThread(TestCriticalThread,this);    UINT TestCriticalThread(LPVOID _this){    CTestSTLFileDlg* testDlg = (CTestSTLFileDlg*)_this;    TestEnterCriticalSection(&test);    Sleep(100);    for (int i = 0;i < 10;i++)        testDlg->TestData[i] = i;    TestLeaveCriticalSection(&test);    return 0;}UINT TestCriticalThread2(LPVOID _this){    CTestSTLFileDlg* testDlg = (CTestSTLFileDlg*)_this;    TestEnterCriticalSection(&test);    for (int i = 10;i < 20;i++)        testDlg->TestData[i] = i;    TestLeaveCriticalSection(&test);    return 0;}   

最近和朋友讨论了一下关与原子量以及计数器的执行原理,应该是通过对硬件的直接操作(比如调用中断达到硬件上的支持)完成计数器的自增或者自减的完成。

0 0