PTHREAD_MUTEX_INITIALIZER与pthread_mutex_init(&mutex, param)的区别

106

是否有任何区别

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

或者

pthread_mutex_t lock;
pthread_mutex_init ( &lock, NULL);

如果我只使用第一种方法,我是否足够安全?

注意:我的问题主要涉及非常小的程序,在最多的情况下,我将连接几个客户端到服务器,并使用工作线程解决他们的查询。

4个回答

85

按照旧版本的POSIX标准,只有在静态分配变量时才保证使用初始化器的第一种方法有效,而不是当变量是在函数体中定义的 auto 变量时。虽然我从未见过不允许这样做的平台,甚至对于 auto 变量也是如此,而且这个限制已经在最新版本的POSIX标准中被删除。

如果您可以使用static变体,那么它真的更可取,因为它使得编写引导代码更加容易。每当运行时进入使用这种互斥锁的代码时,您可以确信该互斥锁已被初始化。这是在多线程环境中宝贵的信息。

使用init函数的方法更可取,当您需要特殊属性的互斥锁时,例如可以递归使用或在进程之间共享,而不仅仅是在线程之间共享时。


15

我想引用这本中的内容:

使用POSIX线程初始化锁有两种方法。一种方法是使用PTHREAD_MUTEX_INITIALIZER,如下所示:pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

这样做会将锁设置为默认值,从而使锁可用。动态初始化锁(即在运行时)是通过调用pthread_mutex_init()来完成的,如下所示:int rc = pthread_mutex_init(&lock, NULL); assert(rc == 0); // 总是检查成功!

这个例程的第一个参数是锁本身的地址,而第二个参数是可选的属性集。阅读更多关于属性的内容,请自行了解;传递NULL只是使用默认值。两种方式都可以工作,但我们通常使用动态(后者)方法。


8
你可以使用动态初始化设置互斥量的更多属性,而且只有在运行时添加一堆互斥量时才能使用动态方法。但是,如果静态方法符合您的需求,那么使用静态方法也没有问题。

“此外,如果您只在运行时添加一堆互斥锁,则只能使用动态方法。”那么这是什么意思?如果不容易解释,可以举个小例子吗? - Kalec
1
@ Kalec:如果您的互斥量是由 malloc() 分配的(或属于分配的对象)。 - Michael Burr
3
如果互斥变量“lock”是一个结构体的一部分,那么我们不能使用第一种方法。我们必须使用pthread_init()。 - pankaj kushwaha

7

如果默认的互斥属性是适当的,可以使用宏PTHREAD_MUTEX_INITIALIZER来初始化互斥锁。

如果您想为互斥锁指定属性,请使用动态初始化........

其效果相当于通过将参数attr指定为NULL调用pthread_mutex_init()进行动态初始化,但是不执行错误检查。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接