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.
Related
I am working on some code which uses the pthread and semaphore libraries. The sem_init function works fine on my Ubuntu machine, but on OS X the sem_init function has absolutely no effect. Is there something wrong with the library or is there a different way of doing it? This is the code I am using to test.
sem_t sem1;
sem_t sem2;
sem_t sem3;
sem_t sem4;
sem_t sem5;
sem_t sem6;
sem_init(&sem1, 1, 1);
sem_init(&sem2, 1, 2);
sem_init(&sem3, 1, 3);
sem_init(&sem4, 1, 4);
sem_init(&sem5, 1, 5);
sem_init(&sem6, 1, 6);
The values appear to be random numbers, and they do not change after the sem_init call.
Unnamed semaphores are not supported, you need to use named semaphores.
To use named semaphores instead of unnamed semaphores, use sem_open instead of sem_init, and use sem_close and sem_unlink instead of sem_destroy.
A better solution (these days) than named semaphores on OS X is Grand Central Dispatch's dispatch_semaphore_t. It works very much like the unnamed POSIX semaphores.
Initialize the semaphore:
#include <dispatch/dispatch.h>
dispatch_semaphore_t semaphore;
semaphore = dispatch_semaphore_create(1); // init with value of 1
Wait & post (signal):
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
...
dispatch_semaphore_signal(semaphore);
Destroy:
dispatch_release(semaphore);
The header file is well documented and I found it quite easy to use.
If you look at the implementation of sem_init in the source then it just returns an error, while some of the other bsd fns like sem_open still have implementation.
Both the "deprecated" posix fns and libdispatch/GCD call from userspace using fns like semphore_create and semaphore_wait. You can use these directly if you want an old-style sema that always uses the kernel/OS, but you're better with ones like from GCD that uses atomic counters internally and only calls the kernel/OS if it has to wait.
https://github.com/apple/darwin-xnu/blob/a1babec6b135d1f35b2590a1990af3c5c5393479/bsd/kern/posix_sem.c
I just started learning about threads, mutexes and condition variables and I have this code:
#include <pthread.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t mutex;
static pthread_mutexattr_t attr;
volatile int x = 0;
void *thread_one_function (void *dummy) {
printf("In func one.");
while (true) {
pthread_mutex_lock (&mutex);
x = rand ();
pthread_cond_signal (&cond);
pthread_mutex_unlock (&mutex);
}
}
void *thread_two_function (void *dummy) {
printf("In func two.");
pthread_mutex_lock (&mutex);
while (x != 10) {
pthread_cond_wait (&cond, &mutex);
}
printf ("%d\n", x);
pthread_mutex_unlock (&mutex);
printf ("%d\n", x);
}
int main (void){
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&mutex, &attr);
pthread_t one, two;
pthread_create(&one,NULL,thread_one_function,NULL);
pthread_create(&two,NULL,thread_two_function,NULL);
//pthread_join(one,NULL); //with this program will not end.
//pthread_join(two,NULL);
return 0;
}
I compile it as gcc prog.c -lpthread -o a.exe
And I am getting no output. Not even that my threads get into those two functions...
What am I doing wrong ? My code is created as a combination from multiple documentations.
Thanks for any help.
The most likely reason for you getting no output is that the main thread returns from the initial call to main() immediately after starting the threads. That terminates the program, including the newly-created threads.
It does not help that neither do the threads' initial messages end with newlines nor do the threads flush the standard output after the printf calls. The standard output is line-buffered when connected to a terminal, so actual delivery of those messages to the terminal will be deferred in your example.
The main thread should join the other two before it terminates. Your code comments indicate that you had other issues when you did that, but going without joining those threads is not a correct solution if in fact you want the additional threads to run to completion. The problem is not joining the threads, but rather that the threads are not terminating.
There's a pretty clear reason why the thread_one_function thread does not terminate, which I am sure you will recognize if you look for it. But what about the thread_two_function thread? The reasons for that taking a long time to terminate are at least twofold:
the more obvious one is the one hinted in #dbush's comment on the question. Consider the range of the rand() function: how many calls do you think it might take before it returns the one, specific result that thread_two_function is looking for?
moreover, how often is thread_two_function even going to get a chance to check? Consider: thread_one_function runs a tight loop in which it acquires the mutex at the top and releases it at the bottom. Pthreads mutexes do not implement any kind of fairness policy, so when thread_one_function loops around and tries to reacquire the mutex immediately after releasing it, it has a very high probability of succeeding immediately, even though thread_two_function may be trying to acquire the mutex too.
It would make more sense for your threads to take turns. That is, after generating a new number, thread_one_function would wait for thread_two_function to check it before generating another. There are several ways you could implement that. Some involve using the same condition variable in thread_one_function that you do in thread_two_function. (Details left as an exercise.) I would suggest also providing a means by which thread_two_function can tell thread_one_function that it doesn't need to generate any more numbers, and should instead terminate.
Finally, do be aware that volatile has no particular place here. It is not useful or appropriate for synchronization, whereas the mutex alone is entirely sufficient for that. It's not exactly wrong to declare x volatile, but it's extraneous.
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.
I am fairly new in threads programming and I wanted to test the mutex functionality. So I programmed the following in order to test it.
**thread_test.h
...
extern int flags;
extern pthread_mutex my_mutex;
...
**thread_test.c
...
#include"thread_test.h"
...
void * thread_test(void *thread_parameters)
{
long tid = (long) thread_parameters;
pthread_mutex_lock(&my_mutex);
++flags;
printf("**THREAD %d** started. Flag value is %d.\n",tid, flags);
sleep(6);
pthread_mutex_unlock(&my_mutex);
pthread_exit(NULL);
}
...
**main.c
...
#include"thread_test.h"
...
#define THREADS 5
pthread_t threads[THREADS];
pthread_mutex_t my_mutex;
int flags = 0;
...
int main(){
int rct;
for(rct = 0; rct<THREADS; rct++)
if(pthread_create(&threads[rct],NULL, thread_test, (void *)rct))
printf("ERROR!")
else
{
sleep(1);
printf("Thread %d initialised in main and the flags value is %d.\n", rct,flags);
}
pthread_mutex_destroy(&my_mutex);
...
It appears that even though I lock the mutex in the child threads, the main program somehow overwrites the mutex lock while a thread has it and assigns variable flags with a new value..
Does anyone have an idea why this is happening?
From what I see you have several errors in your code, part of which your compiler should have told you if you switch all warnings on.
pthread_mutex_t variables must be initialized. For static initialization using = PTHREAD_MUTEX_INITIALIZER at the point of defininition would be enough. (And there is not much point in destroying a static mutex on the other end.)
in the code snippet you gave there is no declaration of thread_test visible to main
you exit main (and destroy the mutex) before the threads have terminated. You may do this, but then you'd have to use an explit pthread_exit in main (and definitively don't do the destroy then). The commonly used approach is not to do this, but to use pthread_join for all threads that have been created.
Also, you could indent your code before posting here, that would much help to make it more readable.
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.