【问题标题】:Should I use condition variables from the C++ standard or from the Windows API?我应该使用来自 C++ 标准还是来自 Windows API 的条件变量?
【发布时间】:2014-02-18 13:51:43
【问题描述】:

在 Win32 C++ 程序中实现条件变量时,最好使用 Win32 函数、类和数据类型(例如 CreateThreadSleepConditionVariableCSWaitForSingleObjectExReleaseMutexCONDITION_VARIABLE)或来自 C++11 标准库的那些(例如threadwaitjoinunlockcondition_variable)?

由于这个问题的答案可能不是二元的,在做出这样的决定时应该考虑哪些因素?

【问题讨论】:

  • 鉴于 Visual Studio 尚未完成标准的实施,如果可移植性不是问题,我现在会使用 Windows 调用。
  • 函数有前置条件和后置条件。当你编写软件时,你就有了“目的”。函数可能满足您的目的或不能满足您的目的,但它们并不是“更好”或“更差”。它们只是函数。
  • @woolstar 我实际上正在使用 Code::Blocks 和最新版本的 MinGW,但这是一个很好的考虑。
  • 你有没有打算跨平台?
  • 在某些情况下没有同类比较。例如,CreateEvent() 可以用 std::condition_varaible 复制,但底层实现有很大不同,因此在尝试使用这些构造时可能会出现性能差异。

标签: c++ winapi c++11 condition-variable


【解决方案1】:

C++ 同步机制是根据 C++ 原则设计的。他们在析构函数中释放资源,并且还使用 RAII 来确保安全锁定。他们使用异常来表示错误。

基本上,它们比基于函数的原生 Windows API 更难被错误使用。这意味着,如果您可以使用它们(您的实现支持它们),您应该始终使用它们。

哦,它们是跨平台的。

【讨论】:

  • 我完全同意。如果您需要这些对象的本机句柄,请使用native_handle() 方法,并了解本机句柄可能并不总是可用,或者可能不是您认为的那样。例如,C++11 库实现中的互斥锁可能会在无争议的情况下使用原子变量,因此除非互斥锁有争议,否则不会有任何可用的本机句柄。
  • 附带一个小提示:VC2012 的线程库实现有很多错误,可能会给您留下难看的竞争条件。因此,除非您已经在使用 VC2013,否则请考虑使用更成熟的 Boost's implementation of the thread library。您不应该注意到两者之间的性能差异,因为它们都是原生 Win32 函数的相当薄的包装器。
  • 如果程序已经包含其他 Win32 代码,它们是否跨平台无关紧要,对吧?除非部分代码可能会重新用于可移植代码。当然,我学习其中一个的好处是得到的知识可以是跨平台的。
  • 是的。你学习了跨平台代码,你可以重用跨平台的部分,如果你想移植,你的工作就更少了。
  • 确实,经过进一步研究和实现了自己的条件变量,我现在明白threadmutexcondition_variable等C++标准库类中使用RAII和异常是做得很好,并且使处理错误比处理 Win32 函数中的错误更简单。此外,一旦您了解了这些类,它们就会非常容易使用。
【解决方案2】:

一个考虑因素应该是您的编译器可以处理什么。例如,当您在 Windows 上安装 MinGW 时,您可以选择是为 POSIX 线程还是 Win32 线程安装 API。另一方面,如果您使用 TDM-GCC,您应该知道 4.7.1 及更低版本使用 Win32 线程,而 4.8.1 及更高版本使用 POSIX 线程。而且正如上面的wootstar所说,如果你使用的是微软的编译器,你应该检查一下它对这些类的支持中的错误是否已经解决。

如果您的编译器支持 POSIX 线程,您可以使用标准库的 C++ 线程类(例如 threadmutexcondition_variable)。如果您的编译器支持 Win32 线程,则可以使用 Win32 线程函数。

就我而言,我最初拥有 TDM-GCC 4.7.1 并尝试使用 C++ 标准库类,但这不起作用(原因如上所述)。所以我自己安装了MinGW,并在安装程序的“threads”选项中选择了“posix”。然后我就可以使用这些类了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 2021-06-15
    相关资源
    最近更新 更多