【问题标题】:Critical section failure临界区故障
【发布时间】:2016-09-19 08:53:42
【问题描述】:

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

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);
}

令我惊讶的是,我收到消息“线程失败!!”当我运行代码时。我认为这是不可能的。我是不是忘记了什么?

【问题讨论】:

  • void void modify ??您可以发布进入/离开部分的代码吗?
  • "void void" 是一个错字 - 现在已修复。当您说发布代码时-您的意思是“//在这里做一堆工作”部分吗?有很多!
  • 首先,您的关键部分似乎很大。不应该,它应该尽可能小,否则线程之间不会有并行性。如果您需要一些共享数据,只需在本地提取(复制)它,然后离开关键部分来处理数据。其次,您的问题很可能出在您没有向我们展示的代码部分。
  • 为什么不可能? set_on_entry由第一个进入临界区的线程初始化,其他线程有不同的sets。
  • 这有什么奇怪的?静态仅由第一个线程初始化一次,其他 3 个只是检查不同的值并且那些不匹配。

标签: c++ multithreading winapi


【解决方案1】:

您的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;

【讨论】:

    【解决方案2】:

    您的问题在于静态变量,而不是您的关键部分。静态变量初始化只执行一次,然后不再执行赋值。

    你要写的是:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-08
      • 2020-08-17
      • 2018-10-17
      • 2013-03-26
      • 2013-04-07
      相关资源
      最近更新 更多