是否有任何理由应该将 C++ 11+ std::mutex 声明为全局变量,而不是作为函数参数传递给 std::thread ?
Posted
技术标签:
【中文标题】是否有任何理由应该将 C++ 11+ std::mutex 声明为全局变量,而不是作为函数参数传递给 std::thread ?【英文标题】:Is there any reason C++ 11+ std::mutex should be declared as a global variable instead of passed into a std::thread as a function parameter? 【发布时间】:2017-07-05 17:37:55 【问题描述】:我见过大多数使用std::mutex
的示例,其中互斥锁是全局的。我想知道这样做有什么具体原因吗?我有自己的程序,但我不这样做,只需将互斥锁作为std::thread
std::ref
传递。拥有全局变量不是不好的做法,如果没有语言限制这样做的理由,C++ 中全局 std::mutexes
背后的原因是什么?
【问题讨论】:
没有理由。可能是为了减少示例中的代码。 可能是因为作者讨厌std::reference_wrapper
的语法;)
这完全取决于。它们是相当琐碎的程序吗?它们是否包含多个文件?需要更多信息。通常全局变量被认为是不好的做法,应该避免。通常我的互斥锁往往是类成员变量。将它们放在需要锁定的对象中通常是很自然的。
【参考方案1】:
拥有全局变量是不好的做法,除非没有全局变量。例如,std::cin
是全局的。
互斥体在某种意义上是全球性的,无论您如何使它们可用。它们在不同的代码段之间共享。因此,您可以使它们成为全局变量,或者您可以通过不使用它们的函数将它们传递到调用链中,直到最终到达使用它们的人。这就是所谓的“流浪数据”,也是“坏习惯”。选择你的毒药。
【讨论】:
旁注:您至少可以通过将各种数据(互斥体等)放在一个对象中来最小化流浪者的数量;那么你只需要在调用链中传递一个参数而不是很多。 @JeremyFriesner -- 是的,您可以创建不连贯的类型来简化糟糕设计的实现。<iostream>
中的global有批评...并不是因为std
中的做法是正确的。
我完全不同意这一点。 A:我的实现通常在***范围内使用互斥锁,B:我的线程通常有另一个数据结构,我需要互斥访问,当您依赖某些可能或可能不实际的全局互斥锁时,您无法移动互斥锁代码存在。 C:您可以创建一个线程类来容纳互斥锁,或者使用一个完全独立的类来组合互斥锁和资源访问。在这种情况下,全局变量看起来仍然像代码异味。
Re,“互斥体在某种意义上是全局的......”您正在寻找的意义可能是 extent (即变量存在多长时间),但是当人们说“全局”而不限定它,他们通常表示全局范围(即代码的哪些部分可以看到它)。 C++ std::mutex
的范围取决于它的声明位置——可以是全局的、可以是本地的、可以是私有成员——就像任何其他类型的变量一样。由于互斥体的目的是防止线程同时访问相同的数据,因此将其声明在与其保护的数据相同的范围内通常是有意义的。【参考方案2】:
这样做很可能是为了使示例更易于理解,允许使用互斥锁本身成为示例的重点,而不是具体细节。
通常,互斥锁保护资源,在许多情况下,互斥锁与资源一起存在是有意义的。例如,如果您有一个包含需要由互斥锁保护的成员容器的类,则使互斥锁也成为该类的成员。然后,当类实例由多个线程作用时,成员互斥锁可用于保护对内部容器的所需访问。
【讨论】:
以上是关于是否有任何理由应该将 C++ 11+ std::mutex 声明为全局变量,而不是作为函数参数传递给 std::thread ?的主要内容,如果未能解决你的问题,请参考以下文章
有啥理由不使用 Visual Studio 6 for C++? [关闭]
是否有任何理由更喜欢在 IDE 中运行应用程序而不是运行独立的可执行文件?