【问题标题】:Critical sections and shutdown / destruction?关键部分和关闭/销毁?
【发布时间】:2014-03-08 21:04:11
【问题描述】:

当您有一个包含临界区 CS 和指向另一个对象 OBJ2 的指针的对象 OBJ1 时,我无法弄清楚正确的关闭过程是什么

假设你有两个函数 A 和 B。

A进入临界区,修改OBJ2中的数据,离开临界区。 B 是一个关闭/销毁程序,应该销毁所有东西(OBJ2、CS 和 OBJ1)

我的问题是:

您如何解决由于 B 已经进入临界区而导致 A 等待进入临界区的场景? B会摧毁一切。如果“破坏”(出于某种有趣的原因)导致/允许 A 进入临界区,则 A 将生成异常,因为它正在尝试访问不再存在的对象。如果“破坏”没有导致 A 进入临界区,那么 A 将永远挂起等待进入临界区。

销毁包含临界区和指向对象的指针的类实例的正确方法是什么?

对我来说,似乎唯一的解决方案是将关键部分作为全局变量,而数据可以放在“类”(结构)中......但我不喜欢那个解决方案!

我使用的语言是 C。我知道 C 中没有类。我有结构的实例。

例子:

typedef struct classX_t
{
   CRITICAL_SECTION cs;
   classY* thisY;
} classX;


typedef struct classY_t
{
   int some_variable;
} classY;

我创建了一个 X 的实例和一个 Y 的实例。变量 'thisY' 指向 Y 的实例。我的两个函数是:

void funcA(classX* thisClassX)
{
   if (thisClassX == NULL) return;
   EnterCriticalSection(thisClassX->cs);

   thisClassX->thisY->some_variable++;

   LeaveCriticalSection(thisClass->cs);
}


void funcB(classX* thisClassX)
{
   if (thisClassX == NULL) return;
   EnterCriticalSection(thisClassX->cs);
   /* free stuff here */
   free(thisClassX->thisY);
   DeleteCriticalSection(thisClass->cs);
   /* and destroy instance */
   free(thisClassX)
}

如果 funcA 正在等待进入临界区,因为 B 已经进入了临界区,那么我看不出 funcA 如何正确执行而不会导致问题。有什么办法解决这个问题?

编辑:

也许我需要某种“锁定”计数;即当某些代码进入临界区时计数器增加 1 并在代码离开临界区时递减?如果我有,那么关闭程序可以检查计数以查看它是否大于 1(表明其他一些代码正在等待进入临界区),如果计数大于 1,那么它可以休眠直到计数消失回到 1。所以这就是我的建议:

每个函数都这样做:

void someFunction(...)
{
    if (thisClassX == NULL) return;
    thisClassX->counter++;
    EnterCriticalSection(thisClassX->cs);
    /* do something */
    LeaveCriticalSection(thisClassX->cs);
    thisClassX->counter--;
}

【问题讨论】:

  • "...销毁一个类的实例..." 那么,这不是一个C语言问题吗?
  • 正如 WhozCraig 所说,您能否说得更具体一些,因为目前还不太清楚您在说什么,而且剪掉的一些代码也会很棒
  • 这是一个很常见的问题,你想到了一切,却忽略了程序关闭。没有神奇的解决方案,而且通常很难解决,因为退出请求是如此完全异步。除了出口(0); C++11 中也包含 std::quick_exit()
  • 我已经编辑了我的问题
  • 其实有一个神奇的解决方案。只需按照您喜欢的任何顺序删除 B 中的所有内容。原因很明显:除非调用 B 的线程是唯一运行的线程(或唯一运行的可能调用 A 的线程),否则不可能以安全的方式执行此操作。这意味着您必须已经退出所有其他线程,因此没有必要同步任何内容。如果有其他线程正在运行(可能调用 A),则对象是否通过 CS“安全”访问和删除并不重要。这将导致访问 invalid 对象。

标签: c windows multithreading mutex critical-section


【解决方案1】:

你可以做的是添加一个开关(一个整数或任何你喜欢的),它告诉每个函数它是否仍然有效/允许改变你的 OBJ。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-13
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多