在 pthread_mutex_init 之前调用 pthread_mutex_lock 安全吗?
Is it safe to call pthread_mutex_lock before pthread_mutex_init?
我以前从未有机会使用 pthreads 库,但我正在审查一些涉及 pthread 互斥锁的代码。我检查了 pthread_mutex_lock
和 pthread_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
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_init
和 PTHREAD_MUTEX_INITIALIZER
创建的。碰巧的是,C 语言还保证在程序启动时将未初始化的全局变量清零。因此,看起来您不需要初始化 pthread_mutex_t
对象,但事实并非如此。特别是在堆栈或堆上的东西通常不会被清零。
在 pthread_lock
之后调用pthread_mutex_init
肯定会产生不良后果。它将覆盖变量。潜在结果:
- 互斥量被解锁。
- 另一个线程试图获取锁的竞争条件,导致崩溃。
- 库或内核中的资源泄漏(但将在进程终止时释放)。
我以前从未有机会使用 pthreads 库,但我正在审查一些涉及 pthread 互斥锁的代码。我检查了 pthread_mutex_lock
和 pthread_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
If
mutex
does not refer to an initialized mutex object, the behavior ofpthread_mutex_lock()
,pthread_mutex_trylock()
, andpthread_mutex_unlock()
is undefined.
因此您确实需要初始化互斥量。这可以通过调用 pthread_mutex_init()
来完成;或者,如果互斥量具有静态存储持续时间,则使用静态初始化器 PTHREAD_MUTEX_INITIALIZER
。例如:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
互斥体是包含函数完成其工作所需的状态(信息)的变量。如果不需要信息,例程就不需要变量。同样,如果您向它提供随机垃圾,例程也可能无法正常运行。
大多数平台确实接受填充了零字节的互斥对象。这通常是 pthread_mutex_init
和 PTHREAD_MUTEX_INITIALIZER
创建的。碰巧的是,C 语言还保证在程序启动时将未初始化的全局变量清零。因此,看起来您不需要初始化 pthread_mutex_t
对象,但事实并非如此。特别是在堆栈或堆上的东西通常不会被清零。
在 pthread_lock
之后调用pthread_mutex_init
肯定会产生不良后果。它将覆盖变量。潜在结果:
- 互斥量被解锁。
- 另一个线程试图获取锁的竞争条件,导致崩溃。
- 库或内核中的资源泄漏(但将在进程终止时释放)。