Windows上的EnterCriticalSection和CRITICAL_SECTION

时间:2013-05-29 14:19:21

标签: windows critical-section

在我的const'中 - 我希望'secondCommand'仅在'firstCommand'之后被调用。我尝试使用EnterCriticalSection,但问题是,在哪里启动我的锁定 - 如果我在构造函数中执行它(在#),并在'firstCommand'之后释放锁(在##),并尝试在'secondCommand'之前再次获取锁(在###),它可能不起作用,因为在###,即使锁被锁定 - 仍然可以调用secondCommand - 因为锁定在同一个thead中(就像连续两次调用“lock”和“lock”一样) - 不会有死锁)。

另一方面,如果我在'firstCommand'之前锁定(在####)并在'firstCommand'之后(在##)发布,当检查锁是否被锁定时 - 锁可以未初始化 - 这会引起问题。这是我的代码:

myClass::myClass (){
    #
    threadFunction();
    ###
    secondCommand();
}

void myClass::threadFunction(){
    DWORD threadID;
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadFunc,0, 0, &threadID);
}

threadFunc(){
    ####
    firstCommand();
    ##
    while(true){};
}

这似乎是一个简单的问题,但我一直想要解决它一个小时。任何人都可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

我认为您最好使用某个活动:查看CreateEventSetEventWaitForSingleObject

您将在构造函数中创建事件,在“###”处等待它,并将其设置为“##”。你应该检查WaitForSingleObject的返回值;如果成功,它将是WAIT_OBJECT_0。

答案 1 :(得分:1)

也许问题的本质并不像你发布的例子那么简单,但一个显而易见的方法就是这样做

myClass::myClass (){
    firstCommand();
    threadFunction();
    secondCommand();
}

void myClass::threadFunction(){
    DWORD threadID;
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadFunc,0, 0, &threadID);
}

threadFunc(){
    while(true){};
}

是否有某些原因导致firstCommand必须在另一个线程上运行?

修改
由于您需要在后台线程上运行firstCommand,然后使用事件来确定何时安全。因此,在myClass中为事件句柄

定义成员变量(或两个线程都可访问的位置)
HANDLE m_hEvent;

并像这样使用

myClass::myClass (){
    m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    threadFunction();
    WaitForSingleObject(m_hEvent, INFINITE);
    secondCommand();
    CloseHandle(m_hEvent);
    m_hEvent = NULL;
}

void myClass::threadFunction(){
    DWORD threadID;
    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadFunc,0, 0, &threadID);
}

threadFunc(){
    firstCommand();
    SetEvent(m_hEvent);
    while(true){};
}

因此,在主线程中,secondCommand等待事件在运行之前发出信号。在工作线程中,事件在firstCommand完成后设置(发出信号)。