在 pthread_mutex_init 之前调用 pthread_mutex_lock 安全吗?

Is it safe to call pthread_mutex_lock before pthread_mutex_init?

我以前从未有机会使用 pthreads 库,但我正在审查一些涉及 pthread 互斥锁的代码。我检查了 pthread_mutex_lockpthread_mutex_init 的文档,从阅读这两个函数的手册页中我的理解是我必须在调用 pthread_mutex_lock.[= 之前​​调用 pthread_mutex_init 28=]

但是我问了几个同事,他们认为在调用pthread_mutex_init之前先调用pthread_mutex_lock是可以的。我正在审查的代码也调用了 pthread_mutex_lock 而没有调用 pthread_mutex_init.

基本上,在调用 pthread_mutex_init 之前调用 pthread_mutex_lock 是否安全且明智(如果 pthread_mutex_init 甚至被调用)?

编辑:我还看到一些示例,其中 pthread_mutex_lock 在未使用 pthread_mutex_init 时被调用,例如 this example

编辑 #2:这是我正在审查的具体代码。请注意,configure 函数获取并附加到一些未初始化的共享内存。 Java 代码稍后将调用 lock(),中间不会调用其他本机函数。 Link to code

这是我在评论中发布的 link 中的文字:

 Mutual exclusion locks (mutexes)  prevent  multiple  threads
 from simultaneously executing critical sections of code that
 access shared data (that is, mutexes are used  to  serialize
 the  execution  of  threads).  All mutexes must be global. A
 successful call for a mutex lock  by  way  of   mutex_lock()
 will  cause  another  thread that is also trying to lock the
 same mutex to block until the owner thread unlocks it by way
 of   mutex_unlock().  Threads  within  the  same  process or
 within other processes can share mutexes.

 Mutexes can synchronize threads within the **same  process**  or
 in  ***other   processes***.  Mutexes  can  be used to synchronize
 threads between processes if the mutexes  are  allocated  in
 writable  memory  and shared among the cooperating processes
 (see mmap(2)), and have been initialized for this task.

Initialize Mutexes are either intra-process or inter-process,
depending upon the argument passed implicitly or explicitly to the initialization of that mutex.
A statically allocated mutex does not need to be explicitly initialized;
by default, a statically allocated mutex is initialized with all zeros and its scope is set to be within the calling process.

 For inter-process synchronization, a mutex needs to be allo-
 cated   in  memory shared between these processes. Since the
 memory for such a mutex must be allocated dynamically,   the
 mutex needs to be explicitly initialized using mutex_init().




also, for inter-process synchronization,
besides the requirement to be allocated in shared memory,
the mutexes must also use the attribute PTHREAD_PROCESS_SHARED,
otherwise accessing the mutex from another process than its creator results in undefined behaviour
(see this: linux.die.net/man/3/pthread_mutexattr_setpshared):

The process-shared attribute is set to PTHREAD_PROCESS_SHARED to permit a
mutex to be operated upon by any thread that has access to the memory
where the mutex is allocated, even if the mutex is allocated in memory that is shared by multiple processes

POSIX standard 说:

If mutex does not refer to an initialized mutex object, the behavior of pthread_mutex_lock(), pthread_mutex_trylock(), and pthread_mutex_unlock() is undefined.

因此您确实需要初始化互斥量。这可以通过调用 pthread_mutex_init() 来完成;或者,如果互斥量具有静态存储持续时间,则使用静态初始化器 PTHREAD_MUTEX_INITIALIZER。例如:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

互斥体是包含函数完成其工作所需的状态(信息)的变量。如果不需要信息,例程就不需要变量。同样,如果您向它提供随机垃圾,例程也可能无法正常运行。

大多数平台确实接受填充了零字节的互斥对象。这通常是 pthread_mutex_initPTHREAD_MUTEX_INITIALIZER 创建的。碰巧的是,C 语言还保证在程序启动时将未初始化的全局变量清零。因此,看起来您不需要初始化 pthread_mutex_t 对象,但事实并非如此。特别是在堆栈或堆上的东西通常不会被清零。

pthread_lock 之后调用pthread_mutex_init 肯定会产生不良后果。它将覆盖变量。潜在结果:

  1. 互斥量被解锁。
  2. 另一个线程试图获取锁的竞争条件,导致崩溃。
  3. 库或内核中的资源泄漏(但将在进程终止时释放)。