C++ 初始化 pthread 互斥锁

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6310746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:53:46  来源:igfitidea点击:

Initializing pthread mutexes

c++c

提问by StackedCrooked

According to the documentationa mutex can be initialized in two ways:

根据文档,可以通过两种方式初始化互斥锁:

Using the init function:

使用初始化函数:

pthread_mutex_t theMutex;
pthread_mutex_init(&theMutex, NULL);

Using an initializer macro:

使用初始化宏:

pthread_mutex_t result = PTHREAD_MUTEX_INITIALIZER;

About the latter the documentation says:

关于后者,文档说:

In cases where default mutex attributes are appropriate, the macro PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes that are statically allocated. The effect shall be equivalent to dynamic initialization by a call to pthread_mutex_init() with parameter attr specified as NULL, except that no error checks are performed.

在默认互斥体属性合适的情况下,宏 PTHREAD_MUTEX_INITIALIZER 可用于初始化静态分配的互斥体。除了不执行错误检查外,效果应等同于通过调用 pthread_mutex_init() 并将参数 attr 指定为 NULL 进行动态初始化。

Does this mean that it may only be used for static variables and not for local variables?

这是否意味着它只能用于静态变量而不能用于局部变量?

C++ Specific

C++ 特定

I wanted to use the following "factory function":

我想使用以下“工厂功能”:

static pthread_mutex_t GetFastNativeMutex()
{
    static pthread_mutex_t result = PTHREAD_MUTEX_INITIALIZER;
    return result;
}

Because it would allow me to initialize mutexes in a C++ initializer list as follows:

因为它允许我在 C++ 初始值设定项列表中初始化互斥体,如下所示:

MyClass() : myMutex(GetFastNativeMutex()) {}

Is this valid? (Btw in practice it works. Valgrind also doesn't complain.)

这是有效的吗?(顺便说一句,在实践中它是有效的。Valgrind 也没有抱怨。)

Update

更新

If I understood the documentation correctly then this should be ok:

如果我正确理解了文档,那么这应该没问题:

#include <pthread.h>

static pthread_mutex_t m0 = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;

However, when looking at the preprocessor output (using gcc -E main.cpp) I see the following:

但是,在查看预处理器输出(使用gcc -E main.cpp)时,我看到以下内容:

static pthread_mutex_t m0 = {0x32AAABA7, {0}};
static pthread_mutex_t m1 = {0x32AAABA7, {0}};
static pthread_mutex_t m2 = {0x32AAABA7, {0}};

It turns out that three times the same mutex was created. What am I doing wrong here?

事实证明,创建了三倍相同的互斥锁。我在这里做错了什么?

回答by David Hammen

Re "It turns out that three times the same mutex was created. What am I doing wrong here?"

回复“结果是创建了 3 次相同的互斥锁。我在这里做错了什么?”

You are doing nothing wrong here. The same mutex was not created three times. It looks like you are interpreting that 0x32AAABA7 as an address. It isn't. It is essentially an enum value, but with a Hamming code protection to (a) make it safe and (b) make it obscure. You have three distinct mutexes here.

你在这里没有做错任何事。没有创建 3 次相同的互斥锁。看起来您正在将 0x32AAABA7 解释为地址。不是。它本质上是一个枚举值,但具有汉明码保护以 (a) 使其安全和 (b) 使其模糊。这里有三个不同的互斥锁。

回答by Andrei

Standard does not allow to copy mutexes by value or return them by value. See http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_mutex_init.html, the paragraph that explicitly talks about this, saying "IEEE Std 1003.1-2001 does not define assignment or equality for this type [pthread_mutex_t]"

标准不允许按值复制互斥锁或按值返回它们。参见http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_mutex_init.html,明确谈到这一点的段落,说“IEEE Std 1003.1-2001 没有定义这种类型的赋值或相等 [pthread_mutex_t]”

The closest relative of pthread_mutex, WIN32 CriticalSection, is absolutely not copyable and not returnable by value. So your API will be very nonportable anyway.

pthread_mutex 的最亲缘关系 WIN32 CriticalSection 绝对不可复制且不可按值返回。所以你的 API 无论如何都是非常不可移植的。

I recommend against copying(returning) mutex by value even you can test it and it works.

我建议不要按值复制(返回)互斥锁,即使您可以测试它并且它可以工作。

Note that initializing a mutex is different from copying already initialized mutex.

请注意,初始化互斥锁与复制已初始化的互斥锁不同。

回答by Khaled Nassar

Just because you can do it, doesn't mean you should.

仅仅因为你可以做到,并不意味着你应该这样做。

The documentation clearly specifies that you use pthread_mutex_initat runtime and the other macro for statically allocated mutexes, I don't see any reason for not doing so.

该文档明确指定您pthread_mutex_init在运行时使用,另一个宏用于静态分配的互斥锁,我看不出有任何理由不这样做。

回答by littleadv

Your GetFastNativeMutexis in no way a factory function. It always returns the copy of the same mutex, the point of factory is to abstract allocation and creation of a new object, not to reuse the same one all the time. So no, this is not valid for any usage that wouldn't be done by using the same mutex as a global variable.

GetFastNativeMutex绝不是工厂功能。它总是返回相同互斥锁的副本,工厂的意义在于抽象分配和创建新对象,而不是一直重用相同的对象。所以不,这对于不能通过使用相同的互斥体作为全局变量来完成的任何用法都无效。

A quote from here:

来自这里的报价:

The result of referring to copies of mutex in calls to pthread_mutex_lock(), pthread_mutex_trylock(), pthread_mutex_unlock(), and pthread_mutex_destroy() is undefined

在调用 pthread_mutex_lock()、pthread_mutex_trylock()、pthread_mutex_unlock() 和 pthread_mutex_destroy() 时引用互斥锁副本的结果未定义

回答by dmeister

It "works" if all myMutex instances should share the same POSIX mutex. You currently have one mutex and not one per MyClass object. This is most certainly not what you want, isn't?

如果所有 myMutex 实例都应该共享相同的 POSIX 互斥锁,则它“有效”。您当前有一个互斥锁,而不是每个 MyClass 对象一个。这肯定不是你想要的,不是吗?