临界截面失效

Critical section failure

本文关键字:失效 截面      更新时间:2023-10-16

几年前我成功地使用了临界区,但我对它是如何工作的记忆已经相当淡忘了。我需要再次使用它们,所以我从我的一个旧项目中剪切和粘贴了一些代码,并创建了以下代码,其中包括一个测试,以确保其按预期工作:

void function_x()
{
    thread t1(modify,  0);
    thread t2(modify,  1);
    thread t3(modify,  2);
    thread t4(modify,  3);
    t1.join();
    t2.join();
    t3.join();
    t4.join();
}
void modify(int set)
{
    // InitializeCriticalSection(&critsecA); already done early in WinWain()
    // misc code here
    blah blah blah, loops etc.
    EnterCriticalSection(&critsecA); 
    static int set_on_entry = set;
    // do a bunch of work here
    blah blah blah, loops etc.
    if (set_on_entry != set)
    {
        error_report("Thread fail!!");
    }
    LeaveCriticalSection(&critsecA);
}

令我惊讶的是,当我运行代码时,我得到了"线程失败!!"的消息。我以为这是不可能的。我忘了什么吗?

您的static int set_on_entry = set;仅由第一个线程执行一次。然后,其他3个线程分别检查if(0 != 1), if(0 != 2), if(0 != 3),结果显然都是true

如果您希望每个线程有一个set_on_entry,请使用thread_local:

static thread_local int set_on_entry = set;

你的问题出在静态变量上,而不是临界区。静态变量初始化只执行一次,然后不再执行赋值。

你要写的是:

static int set_on_entry = 0;//or whatever value, will be overwritten
set_on_entry = set;