A mutex is used to prevent two or more threads to access the same resource (file, variable, ..) at the same time. This prevents a race condition to happen.
Every thread has its own stack. This means when a thread calls a function, the thread will have a unique copy of the local variables defined in this function. But if a local variable is defined as static
, only one copy of this variable will be created and this copy will be accessed by all threads.
Does this mean that a local NON-static
mutex is useless?
Can a static
local mutex be useful? Maybe for guarding a static
local variable?
How does defining a global mutex as static
make as a difference?
The difference between static global variables and static local variables is that a static global variable can be accessed from anywhere inside the program while a static local variable can be accessed only where its scope exists (i.e block scope).
The global mutex is a recursive mutex with a name of "QP0W_GLOBAL_MTX". The global mutex is not currently used by the pthreads run-time to serialize access to any system resources, and is provided for application use only. The maximum number of recursive locks by the owning thread is 32,767.
A mutex has whatever scope you assign to it. It can be global or local again based on where and how you declare it.
A static variable can be either a global or local variable. Both are created by preceding the variable declaration with the keyword static. A local static variable is a variable that can maintain its value from one function call to another and it will exist until the program ends.
A non-static local mutex can still be useful: If you have a main thread that creates the other threads and waits for them to finish, the mutex can be a local variable in the main thread, and it would pass a pointer to that mutex to the other threads. This works only if it's guaranteed that the main thread outlives the others.
If the mutex variable is declared as static
inside your thread function, it will be shared between different threads which use this function, and they can use it for synchornization. This is because static
variables have the same lifetime as global variables (and only one unique copy). However, this only works if your threading library doesn't require a function call to initialize the mutex, as there wouldn't be a good place to do that initialization from.
Another option is to dynamically allocate the mutex, or, more commonly, to have it as a member of a dynamically allocated struct. You can then pass a pointer to the mutex (or containing struct) to all the threads which need it.
As for your last question: Defining a global variable as static
means that it's only visible in the current translation unit. It doesn't affect its lifetime, so will work similarly to non-static globals for this use-case (as long as you only need to access it in one .c file).
Local to a thread callback function is useless - a mutex that isn't shared between multiple functions doesn't make much sense. You can however make it local static
for the sake of reducing scope/global namespace clutter, then share it between functions through pointers. Such as for example have the main thread create it and then pass it along to different threads during creation. This often makes the most sense - to have one thread responsible for the creation and clean-up of all threads and mutexes etc in the project.
A classic bug is to have one thread create resources by passing along local variables with automatic storage (saved on stack) to threads, then that thread goes out of scope and the variables turn invalid. Therefore it is custom to either use static
or dynamic memory allocation for such variables, so that they persist throughout the whole execution of the program.
The term "global" is confusing and poorly-defined. Usually it means global to the whole project. Where as a variable declared outside any function has file scope, but such a variable may have either external or internal linkage. External meaning "global". But if you declare a file scope variable static
, it gets internal linkage and is only visible to the .c file where it was declared. This is a good thing, because it reduces scope and prevents spaghetti programming with global variables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With