检查pthread_mutex是否被初始化

使用pthreads必须在获取锁之前在任何互斥量上调用pthread_mutex_init()。

根据POSIXlocking一个未初始化的互斥体只为具有优先级保护的互斥体定义( opengroup:pthread_mutex_lock )

根据联机帮助页pthread_mutex_lock.3thr ,如果调用一个未经初始化的互斥锁,它应该返回EINVAL。 假设可移植性不是问题,那么编写如下代码是否有效(一个好主意?):

pthread_mutex_t lock; int ret = pthread_mutex_lock(&lock); if (ret != 0){ if(ret == EINVAL){ pthread_mutex_init(&lock, NULL); } else { /* other error */ } } 

是否有另一种方法来检查一个pthread_mutex是否已经初始化?

整个场景是图书馆的一部分(不幸的是不是C ++),我想避免错误的使用。 也就是说,客户端可以初始化两次创build的对象,可以在正确初始化之前将对象传递给其他函数。

目前在对象中有一个标志是否已经初始化了互斥体,我想知道这是否真的有必要。

看看macrosPTHREAD_MUTEX_INITIALIZER对于静态互斥锁初始化的扩展,它只是展开成一个所有成员设置为0的结构体。如果不再需要,我可以假定不需要调用mutex_destroy,因为资源本身被释放如果没有人使用它)?

更新:Jens的答案是绝对正确的 。 以下程序产生完全未定义的行为:

 int main(int argc, char** argv) { pthread_mutex_t lock; int ret = pthread_mutex_lock(&lock); if (ret != 0) { printf(" ERR : %d %s \n", ret, strerror(ret)); if (ret == EINVAL) { pthread_mutex_init(&lock, NULL); } } else { printf(" ok \n"); } pthread_mutex_unlock(&lock); return 0; } 

有时它会死锁,有时候它打印好了…..

不,你不能检测到。 EINVAL 可能会返回一个未初始化的互斥量,但它不一定。

另外POSIX声明:

尝试初始化已经初始化的互斥体会导致未定义的行为。

所以你不应该尝试。

最好的办法是完全避免这种情况,并正确初始化变量。 这应该用宏PTHREAD_MUTEX_INITIALIZER

 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;