Pthread: when Dynamic mutex initialization must be used - c

As everyone knows, there are two ways how to init pthread mutex (C language)
Static initialization:
pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
Dynamic initialization:
pthread_mutexattr_t attr;
pthread_mutex_t mutex;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP);
pthread_mutex_init(&mutex, &attr);
var 1 - I used it many times.
var 2 - the reason I posted this question:
Will really appreciate if someone could provide me with some real example(s) when dynamic initialization of pthread mutex must be used.
Thanks!

You always need the pthread_*_init() functions if the default attributes won't do/are not suitable.
An example can be found at the bottom of this page.

Related

Problem in communication of three threads in C language (deadlock occurs)

I am creating a program in which i have 3 linked lists and I am trying to update or remove the nodes from these linked lists in these three threads. But the deadlock is occurring
The insertion and deletion is working fine. Here the three variables var1InUse,var2InUse and var3InUse are indicating that whether the 3 linked lists are in use or not(Not all three are use in the all threads). I am putting the threads on waiting based on var1InUse,var2InUse and var3InUse as you can see in the code. Sometimes this works fine but sometimes deadlock happens. I have searched for the solution on the internet but could find it.
Am I using the wait and signal methods correctly?
pthread variables declaration
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t t1cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t t2cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t t3cond = PTHREAD_COND_INITIALIZER;
int var1InUse=0,var2InUse=0,var3InUse=0;
THREAD 1
void* thread1(void* args){
while(var1InUse || var2InUse ) {
pthread_cond_wait(&t1cond,&myMutex);}
var1InUse=1,var2InUse=1;
while(1){
pthread_mutex_lock(&myMutex);
/*
some other code about adding and removing from
linkedlist
*/
var1InUse=0,var2InUse=0;
pthread_cond_signal(&t2cond);
pthread_cond_signal(&t3cond);
pthread_mutex_unlock(&myMutex);}
}
THREAD 2
void* thread2(void* args){
while(var1InUse || var2InUse || var3InUse) {
pthread_cond_wait(&t2cond,&myMutex);}
var1InUse=1,var2InUse=1,var3InUse=1;
while(1){
pthread_mutex_lock(&myMutex);
/*
some other code adding and removing from linkedlist
*/
var1InUse=0,var2InUse=0,var3InUse=0;
pthread_cond_signal(&t1cond);
pthread_cond_signal(&t3cond);
pthread_mutex_unlock(&myMutex);}
}
THREAD 3
void* thread3(void* args){
while(var1InUse || var3InUse ) {
pthread_cond_wait(&t3cond,&myMutex);}
var1InUse=1,var3InUse=1;
while(1){
pthread_mutex_lock(&myMutex);
/*
some other code adding and removing from linkedlist
*/
var1InUse=0,var3InUse=0;
pthread_cond_signal(&t1cond);
pthread_cond_signal(&t2cond);
pthread_mutex_unlock(&myMutex);}
}
MAIN METHOD
int main(){
pthread_t t1,t2,t3,t4;
pthread_mutex_init(&myMutex,0);
pthread_create(&t1,NULL,thread1,NULL);
pthread_create(&t2,NULL,thread2,NULL);
pthread_create(&t3,NULL,thread3,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
pthread_mutex_destroy(&myMutex);
return 0
}
I want the deadlock to be removed.
The mutex used by pthread_cond_wait() needs to locked before the function is called. Here is an extract from the man page:
The pthread_cond_timedwait() and pthread_cond_wait() functions shall block on a condition variable. The application shall ensure that these functions are called with mutex locked by the calling thread; otherwise, an error (for PTHREAD_MUTEX_ERRORCHECK and robust mutexes) or undefined behavior (for other mutexes) results.
Although pthread_cond_wait() unlocks the mutex internally, it is locked again before the function returns successfully:
Upon successful return, the mutex shall have been locked and shall be owned by the calling thread.
Additionally, you should access the shared variables var1InUse, var2InUse and var3InUse with the mutex locked.
Here is a modified version of your thread1() that follows these rules. The modifications to the other thread start routines should be similar:
void* thread1(void* args){
pthread_mutex_lock(&myMutex);
while(var1InUse || var2InUse ) {
pthread_cond_wait(&t1cond,&myMutex);
}
var1InUse=1,var2InUse=1;
pthread_mutex_unlock(&myMutex);
while(1){
pthread_mutex_lock(&myMutex);
/*
some other code about adding and removing from linkedlist
*/
var1InUse=0,var2InUse=0;
pthread_cond_signal(&t2cond);
pthread_cond_signal(&t3cond);
pthread_mutex_unlock(&myMutex);
}
return NULL;
}
(I'm not entirely sure that the above is correct, because it's not entirely clear from the original code what the while(1) loop is supposed to do.)

POSIX SHARED - RECURSIVE Mutex

I'm working on linux.
In my code I'm trying to run a few threads ( lets say 2 for example) that are trying to lock a RECURSIVE mutex, but only one thread can access and lock the mutex while the second one gets an EBUSY error even after the first thread has unlocked it. I think it's because the mutex is PRIVET and not SHARED.
I'm trying to set the mutex to be both RECRUSIVE and SHARED like this:
void
MutexCreate(pthread_mutex_t* _m)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(_m, &attr);
}
(I do check for function errors - and all of them return 0)
Even if I try to make it a DEFAULT SHARED mutex by :
void
MutexCreate(pthread_mutex_t* _m)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(_m, &attr);
}
it still remains PRIVET.
Any ideas?
If you really have two threads inside the same process the pshared attribute shouldn't have an influence.
EBUSY is only permitted as a return for pthread_mutex_trylock, so I suppose you used this.
The only explanation that I have is that you maybe locked your mutex several times with the first thread. lock and unlock always come in pairs, make sure that you have as many unlocks as you have locks.

C: How do you declare a recursive mutex with POSIX threads?

I am a bit confused on how to declare a recursive mutex using pthread.
What I try to do is have only one thread at a time be able to run a piece of code(including functions) but after scepticism I figured out that the use of mutexes would not work and that instead I should use recursive mutexes. Here is my code:
pthread_mutex_lock(&mutex); // LOCK
item = queue_peek(queue); // get last item in queue
item_buff=item; // save item to a buffer
queue_removelast(queue); // remove last item from queue
pthread_mutex_unlock(&mutex); // UNLOCK
So what I try to do is just read/remove from the queue serially.
The thing is that there isn't any example out there on how to declare recursive mutexes. Or there maybe a few but they don't compile for me.
The code from Michael Foukarakis is almost good but he initializes the mutex twice which leads to undefined behavior. It should just be:
pthread_mutex_t Mutex;
pthread_mutexattr_t Attr;
pthread_mutexattr_init(&Attr);
pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&Mutex, &Attr);
I actually use this code in production, and I know it works correctly on Linux, Solaris, HP-UX, AIX, Mac OSX and FreeBSD.
You also need to add proper linker flag to compile this:
AIX, Linux, FreeBSD:
CPLATFORM += -pthread
mingw32:
LDFLAGS += -lpthread
To create a recursive mutex, you can either use:
#include <pthread.h>
/* Don't forget to check the return value! */
int pthread_mutexatttr_settype(pthread_mutexattr_t *attr,
int type);
where type is PTHREAD_MUTEX_RECURSIVE, or an initialiser.
For example:
/* ..or PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutexattr_t mta;
or alternatively, initialize at runtime (don't do both, it's undefined behaviour):
pthread_mutexattr_init(&mta);
/* or PTHREAD_MUTEX_RECURSIVE_NP */
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &mta);
On Linux (but this is non portable to other systems), if the mutex is a global or static variable, you could initialize it like
static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
(and by the way, the example is from pthread_mutex_init(3) man pages!)
You need to add mutex attributes when creating the mutex.
Call pthread_mutexattr_init, then pthread_mutexattr_settype with PTHREAD_MUTEX_RECURSIVE then use these attributes with pthread_mutex_init. Read man pthread_mutexattr_init for more info.

reusing pthread_t variable for currently running threads

I'm abit uncertain if the following code will lead to undefined behavior.
//global
pthread_t thread1;
void *worker(void *arg){
//do stuff
}
void spawnThread(){
//init stuff
int iret1 = pthread_create( &thread1, NULL, worker, (void*) p);
}
My spawnThread will make a new thread using the global thread1.
If I'm currently running a thread that is not finished, will I somehow cause undefined behaviour when starting a new thread using the thread1 variable?
If this is a problem, would it make sense to make my pthread_t variable local to a function? I think it might be problem because it will use the stack, and as soon as i return from my function that will be removed.
If I make my pthread_t local to a function, I can't use the pthread_join in a another part of my program. Is the canonical solution, to have a mutex'ed counter keeping track of how many current threads are running?
thanks
The pthread_t is just an identifier. You can copy it round or destroy it at will. Of course, as you mention, if you destroy it (because it is local) then you cannot use it to call pthread_join.
If you reuse the same pthread_t variable for multiple threads then unless there is only one thread active at a time you are overwriting the older values with the new ones, and you will only be able to call pthread_join on the most recently started thread. Also, if you are starting your threads from inside multiple threads then you will need to protect the pthread_t variable with a mutex.
If you need to wait for your thread to finish, give it its own pthread_t variable, and call pthread_join at the point where you need to wait. If you do not need to wait for your thread to finish, call pthread_detach() after creation, or use the creation attributes to start the thread detached.
pthread_t is just an identifier, and you can do whatever you like with it. Thread state is maintained internally in the C library (in the case of Glibc/NPTL, on an internal struct thread on Thread Local Storage, accessed on x86 via the GS register).
Problem is, your thread1 variable is the only way to refer to your first thread.
The solution I often use is having an array of pthread_t where to store the thread ids I need to refer to. In this example it's a static array, but you can also use dynamically alloced memory.
static pthread_t running_threads[MAX_THREAD_RUNNING_LIMIT];
static unsigned int running_thread_count = 0;
// each time you create a new thread:
pthread_create( &running_threads[running_thread_count], blabla...);
running_thread_count++;
// don't forget to check running_thread_count against the size
// of your running thread size MAX_THREAD_RUNNING_LIMIT
When you need to join() them, simply do it in a loop:
for(i =0; i<running_thread_count; i++)
{
pthread_join(&running_threads[i], &return_value);
}

How does Mutex scope work

How does mutex scope work exactly.
If I want 3 mutexes for different things and place them as so
static pthread_mutex_t watchdogMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t watchdogCond = PTHREAD_COND_INITIALIZER;
int waitingForGpsSetupThread = 1;
static pthread_mutex_t gpsRunningMutex = PTHREAD_MUTEX_INITIALIZER;
int gpsRunning = 0;
static pthread_mutex_t indoorNavigationRunningMutex = PTHREAD_MUTEX_INITIALIZER;
int indoorSystemRunning = 0;
Are the variables defined within the scope of the first above mutex declaration or how does it work?
These are just C variables. It doesn't matter in what order you declare them. What matters is in what order you try to acquire/lock the mutexes if you want to hold them at the same time (as in "always acquire resources in the same order" mantra).
Edit 0:
Looks like you can use some introductory threads material:
POSIX Threads Programming
Pthreads Tutorial
I still remember how to google ... :)
As written, the three mutexes are all in the same scope. There are no blocks marked by '{...}' to indicate otherwise. The same would be true if the types were all int. From that point of view, a mutex is no different from any other type.
At the point of use, you would do something like:
pthread_mutex_lock(&watchdogMutex);
...operations protected by the watchdog mutex...
pthread_mutex_unlock(&watchdogMutex);
The bit in the middle could be said to be the scope in which the mutex is locked. It would be a very bad idea to have a return statement in the middle of those operations - unless the mutex was also unlocked before returning.
See the POSIX definitions.

Resources