【发布时间】:2014-08-19 13:06:45
【问题描述】:
使用 pthread 必须在获得锁之前对任何互斥体调用 pthread_mutex_init()。
根据 POSIX,锁定未初始化的互斥锁仅针对具有优先级保护的互斥锁定义 (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++),我想避免最大程度的错误使用。 IE。客户端可能会初始化两次创建的对象,可能会在正确初始化之前将对象传递给其他函数等。
目前对象中有一个附加标志,用于标记互斥锁是否已初始化,我想知道这是否真的有必要。
查看宏 PTHREAD_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;
}
有时它会死锁,有时它打印正常。 .....
【问题讨论】:
-
与其尝试检查互斥锁是否已初始化,不如去了解它。