Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to call pthread_mutex_lock before pthread_mutex_init?

Tags:

c

mutex

pthreads

I've never had the chance to play with the pthreads library before, but I am reviewing some code involving pthread mutexes. I checked the documentation for pthread_mutex_lock and pthread_mutex_init, and my understanding from reading the man pages for both these functions is that I must call pthread_mutex_init before I call pthread_mutex_lock.

However, I asked a couple colleagues, and they think it is okay to call pthread_mutex_lock before calling pthread_mutex_init. The code I'm reviewing also calls pthread_mutex_lock without even calling pthread_mutex_init.

Basically, is it safe and smart to call pthread_mutex_lock before ever calling pthread_mutex_init (if pthread_mutex_init even gets called)?

EDIT: I also see some examples where pthread_mutex_lock is called when pthread_mutex_init is not used, such as this example

EDIT #2: Here is specifically the code I'm reviewing. Please note that the configure function acquires and attaches to some shared memory that does not get initialized. The Java code later on will call lock(), with no other native functions called in-between. Link to code

like image 664
AleW Avatar asked Jul 27 '15 21:07

AleW


People also ask

Is it necessary to call Pthread_mutex_destroy?

From IEEE documentation which is the standard governing POSIX: The documentation does not say you must call it. But it is a good practice to do so. Calling this api will signal the POSIX library to release all the resources which were reserved for use of this particular mutex object during its initialization.

Does pthread_mutex_lock use any system calls?

An instance of a pthread_mutex_t should be defined globally and initialized when it is declared with the macro PTHREAD_MUTEX_INITIALIZER. There are three system calls which perform operations on a mutex, each of which takes a pointer to a pthread_mutex_t as an argument. int pthread_mutex_lock(pthread_mutex_t *mutex);

What is the use of pthread_mutex_lock?

The pthread_mutex_lock() function acquires ownership of the mutex specified. If the mutex currently is locked by another thread, the call to pthread_mutex_lock() blocks until that thread relinquishes ownership by a call to pthread_mutex_unlock().

What is use of pthread_mutex_init ()?

The pthread_mutex_init() function initializes a mutex with the specified attributes for use. The new mutex may be used immediately for serializing critical resources. If attr is specified as NULL, all attributes are set to the default mutex attributes for the newly created mutex.


2 Answers

Mutexes are variables containing state (information) that functions need to do their job. If no information was needed, the routine wouldn't need a variable. Likewise, the routine can't possibly function properly if you feed random garbage to it.

Most platforms do accept a mutex object filled with zero bytes. This is usually what pthread_mutex_init and PTHREAD_MUTEX_INITIALIZER create. As it happens, the C language also guarantees that uninitialized global variables are zeroed out when the program starts. So, it may appear that you don't need to initialize pthread_mutex_t objects, but this is not the case. Things that live on the stack or the heap, in particular, often won't be zeroed.

Calling pthread_mutex_init after pthread_lock is certain to have undesired consequences. It will overwrite the variable. Potential results:

  1. The mutex gets unlocked.
  2. A race condition with another thread attempting to get the lock, leading to a crash.
  3. Resources leaked in the library or kernel (but will be freed on process termination).
like image 159
Potatoswatter Avatar answered Oct 21 '22 22:10

Potatoswatter


The POSIX standard says:

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.

So you do need to initialise the mutex. This can be done either by a call to pthread_mutex_init(); or, if the mutex has static storage duration, by using the static initializer PTHREAD_MUTEX_INITIALIZER. Eg:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
like image 33
caf Avatar answered Oct 21 '22 23:10

caf