【问题标题】:How to expose a thread-safe interface that allocate resources?如何公开分配资源的线程安全接口?
【发布时间】:2021-05-13 04:59:52
【问题描述】:

我正在尝试为我的 C++ 库公开一个 C 接口。这尤其涉及允许用户创建、启动、查询状态,然后释放后台任务的功能。

该任务在 C++ 类中实现,通过std::mutex 保护其成员免受并发读/写。

当我为此后台任务公开 C 接口时,我的问题就出现了。基本上我说了以下函数(假设task_t 是一个不透明的指针,指向包含真正任务类的实际结构):

task_t* mylib_task_create();
bool mylib_task_is_running(task_t* task);
void mylib_task_release(task_t* task);

我的目标是使这些函数的任何并发使用都是线程安全的,但是我不确定具体如何,即如果客户端代码线程同时调用 mylib_task_is_running()另一个线程调用mylib_task_release(),然后一切都很好。

起初我想在task_t 的实现中添加一个std::mutex,但这意味着mylib_task_release() 末尾的delete 语句必须在互斥锁未持有时发生,这意味着它并不能完全解决问题。

我也考虑过使用某种引用计数,但我最终还是遇到了同样的问题,即在调用假设的 retain() 函数后可能立即发生实际删除。

我觉得应该有一个(相对)简单的解决方案,但我不能完全投入其中。我怎样才能做到这一点,这样我就不必强制客户端代码保护对 task_t 的访问?

【问题讨论】:

  • 你不能只获取mylib_task_release() 中的task_t 互斥锁吗?
  • 那么问题是,如果互斥锁是 task_t 结构的成员,那么我需要在互斥锁被锁定时删除任务,并且按照referenceThe behavior is undefined if the mutex is owned by any thread or if any thread terminates while holding any ownership of the mutex. 跨度>
  • shared_pointer 不能解决这个问题吗?
  • @Devolus 怎么样?
  • 好吧,祝你好运。我差点忘了。这是一个简单/粗略的任务块示例,我将其放在一起作为答案:stackoverflow.com/questions/64324334/… 另外,linux 内核源代码将是一个很好的资源

标签: c++ c multithreading thread-safety


【解决方案1】:

如果 task_t 正在被删除,你应该确保没有其他人有指向它的指针。

如果一个线程正在删除 task_t,而另一个线程正在尝试获取它的互斥锁,那么显然您不应该删除 task_t。

shared_ptrs 对此有很大帮助。

【讨论】:

  • 感谢您提供答案。我不确定shared_ptr 将如何帮助您描述,因为这是一个 C API,以及如何确保没有其他人拥有指向任务的指针,因为该 API 返回指针并且我无法控制客户端代码用这个指针做什么。在已发布的任务上调用 API 函数是否有意义,是的。但我主要担心的是它至少不会崩溃。
  • 我刚刚重新阅读了您的问题——困难的情况是“running() 被调用,而 release() 应该释放资源”。这已经表明您的互斥锁需要更高级别,并且由于您不想在 Task* 被销毁后访问它,因此它向我暗示您需要跟踪哪些任务是无效的。您需要一个“TaskManager”类来执行同步并确保 Task* 在获取互斥锁后有效。
  • 是的,我开始意识到我需要一个更高级别的机制来跟踪它,并且可能以非侵入性的方式将任务与互斥锁相关联。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多