-7

当我尝试学习多线程时,我从谷歌搜索中获得了以下代码。我在使用 CRITICAL SECTION 和没有 CRITICAL SECTION 的情况下运行代码,但是在执行这两种情况之后,我不明白为什么这段代码的作者使用 CRITICAL SECTION。

static unsigned int counter = 100;
static bool alive = true;
CRITICAL_SECTION cs;


static unsigned __stdcall Sub(void *args)
{
    while(alive)
    {
        EnterCriticalSection(&cs);
        cout << "[Sub(" << counter << ")]---" << endl;
        counter -= 10;
        LeaveCriticalSection(&cs);
        Sleep(500);
    }

    return 0;
}

static unsigned __stdcall Add(void *args)
{
    while(alive)
    {
        EnterCriticalSection(&cs);
        cout << "[Add(" << counter << ")]+++" << endl;
        counter += 10;
        LeaveCriticalSection(&cs);
        Sleep(500);
    }

    return 0;
}


int _tmain(int argc, _TCHAR* argv[])
{
    InitializeCriticalSection(&cs);

    unsigned add;
    HANDLE hAdd = (HANDLE)_beginthreadex(0,0,&Add,0,CREATE_SUSPENDED, &add);
    assert(hAdd != 0);

    unsigned sub;
    HANDLE hSub = (HANDLE)_beginthreadex(0,0,&Sub,0,CREATE_SUSPENDED, &sub);
    assert(hSub != 0);

    //start threads
    ResumeThread(hAdd);
    ResumeThread(hSub);

    //let threads run for 10 seconds
    Sleep(3000); 

    alive = false;
    WaitForSingleObject(hSub, INFINITE);
    CloseHandle(hSub);
    WaitForSingleObject(hAdd, INFINITE);
    CloseHandle(hAdd);

    return 0;
}
4

2 回答 2

2

您有两个线程并行运行,读取(cout << "[Sub(" << counter << ")]---" << endl)和读取/写入(counter -= 10)共享变量)。如果在读取和写入之间,另一个线程写入该值,您认为会发生什么?如果您尝试counter当同一变量的两次不同读取可能返回不同的值时,根据 的值做出决定?

以下顺序可能(可能会或可能不会)发生:

thread SUB: read counter [say, 100]
thread ADD: read counter [100]
thread ADD: write counter <- 110
thread SUB: write counter <- 90

使用 CRITICAL_SECTION,您可以:

thread SUB: read counter [say, 100]
thread SUB: write counter <- 90
thread ADD: read counter [90]
thread ADD: write counter <- 100

或者你会有:

thread ADD: read counter [100]
thread ADD: write counter <- 110
thread SUB: read counter [110]
thread SUB: write counter <- 100

无论哪种方式,使用 CRITICAL_SECTION,最终结果是 100,如果没有您,最终结果可能是 90。

CRITICAL_SECTION 允许代码块作为“工作单元”执行,而不会受到阻塞在同一 CRITICAL_SECTION 上的另一个线程的干扰。

于 2013-05-21T18:06:48.153 回答
1

CRITICAL_SECTION是一种简单的多线程同步机制。您使用 CRITICAL_SECTION 来保护代码块免受两个或多个线程同时运行。

在大多数情况下,无论有无,您都不会看到差异,它可以保护共享资源免遭碾压,例如:

想象一下,两个线程同时访问像一块内存一样的资源,一个从其中读取图像,而另一个正在向其中写入图像。读取线程将获得损坏的图像。

我建议您多阅读多线程,以更好地理解概念以及如何使用同步对象来控制多线程应用程序中的流程。

  1. http://www.codeproject.com/Articles/7953/Thread-Synchronization-for-Beginners
  2. http://msdn.microsoft.com/en-us/library/windows/desktop/ms681924(v=vs.85).aspx
于 2013-05-21T18:05:22.183 回答