Solve race condition during semaphore initialization - c

I have an array that must be shared between threads, protected by a semaphore. I've put the initialization code inside a function that can be called multiple times, a "constructor", as follows:
#include <stdbool.h> //for bool
#include <semaphore.h>
sem_t global_mutex;
char global_array[N]; // Protected with global_mutex
struct my_struct *new_my_struct(){
static bool is_init = false; // This will be initialized only once, right?
if (!is_init){ // 1
sem_init(&global_mutex, 0, 1); // 2
sem_wait(&global_mutex); // 3
if (!is_init){ // 4
is_init = true; // 5
... initialize global_array ... // 6
}
sem_post(&global_mutex); // 7
}
... proceed on the create and return a my_struct pointer ...
}
In an ideal world, a thread would run from 1 to 7, initialize the array and exit the critical region. Even if another thread had stopped in 2, the test in 4 would be false and the array wouldn't be overwritten. I haven't thinked much of what would happen if a thread stuck in 1 and reinitialized the semaphore, but I believe it isn't of much concern as long as is_init be set to true by the first thread to run!
Now, there is a race condition if a thread stops in 4, and another one runs from the beggining to completion, initializing and populating the global_array. When the thread stopped at 4 runs, it will reinitialize the array and delete the state stored by the first thread.
I would like to know if there is any way to not suffer that race condition (maybe a clever use of static?) or if I should separate the initialization code from the constructor and use it in the main thread, when there's no concurrency.
This code is in use and I haven't suffered from a race condition yet. However, as I know its possible, I'd wish to correct it.

If the real use of the semaphore is really as a mutex, use just that pthread_mutex_t. These can be initialized statically, so your problem would disappear.
The syntax would be
pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
If you really need a dynamic initialization of a global object, have a look into pthread_once. This is the type (pthread_once_t) and function that is foreseen by POSIX for such a task.

There are a few ways to do thread-safe lazy initialization, but this isn't one of them.
pthread_once is one way, and using a global mutex that's actually a mutex (initialized statically) to synchronize the initialization is another. Implementations might guarantee thread-safe initialization of static local variables, but don't have to (at least, they didn't prior to C11 and I haven't checked that).
However you synchronize the actual initialization, though, double-checked locking is not guaranteed to work in C or in Posix. It's a data race to check a flag in one thread, that was set in another thread, without some kind of synchronization in both threads. The implementation of pthread_once should do its best to be fast in the common case that the initialization has already been done. If your implementation guarantees thread-safe intialization of function-scoped static variables, then that will also do its best. Unless you really know what you're doing (e.g. you're implementing pthread_once yourself for some new system), use one of those in preference to rolling your own attempt to avoid costly locking in the common case.

Related

Is a mutex lock used inside a shared function or outside of it

Assume sharedFnc is a function that is used between multiple threads:
void sharedFnc(){
// do some thread safe work here
}
Which one is the proper way of using a Mutex here?
A)
void sharedFnc(){
// do some thread safe work here
}
int main(){
...
pthread_mutex_lock(&lock);
sharedFnc();
pthread_mutex_unlock(&lock);
...
}
Or B)
void sharedFnc(){
pthread_mutex_lock(&lock);
// do some thread safe work here
pthread_mutex_unlock(&lock);
}
int main(){
...
sharedFnc();
...
}
Let's consider two extremes:
In the first extreme, you can't even tell what lock you need to acquire until you're inside the function. Maybe the function locates an object and operates on it and the lock is per-object. So how can the caller know what lock to hold?
And maybe the code needs to do some work while holding the lock and some work while not holding the lock. Maybe it needs to release the lock while waiting for something.
In this extreme, the lock must be acquired and released inside the function.
In the opposite extreme, the function might not even have any idea it's used by multiple threads. It may have no idea what lock its data is associated with. Maybe it's called on different data at different times and that data is protected by different locks.
Maybe its caller needs to call several different functions while holding the same lock. Maybe this function reports some information on which the thread will decide to call some other function and it's critical that state not be changed by another thread between those two functions.
In this extreme, the caller must acquire and release the lock.
Between these two extremes, it's a judgment call based on which extreme the situation is closer to. Also, those aren't the only two options available. There are "in-between" options as well.
There's something to be said for this pattern:
// Only call this with `lock` locked.
//
static sometype foofunc_locked(...) {
...
}
sometype foofunc(...) {
pthread_mutex_lock(&lock);
sometype rVal = foofunc_locked(...);
pthread_mutex_unlock(&lock);
return rVal;
}
This separates the responsibility for locking and unlocking the mutex from whatever other responsibilities are embodied by foofunc_locked(...).
One reason you would want to do that is, it's very easy to see whether every possible invocation of foofunc() unlocks the lock before it returns. That might not be the case if the locking and unlocking was mingled with loops, and switch statements and nested if statements and returns from the middle, etc.
If the lock is inside the function, you better make damn sure there's no recursion involved, especially no indirect recursion.
Another problem with the lock being inside the function is loops, where you have two big problems:
Performance. Every cycle you're releasing and reacquiring your locks. That can be expensive, especially in OS's like Linux which don't have light locks like critical sections.
Lock semantics. If there's work to be done inside the loop, but outside your function, you can't acquire the lock once per cycle, because it will dead-lock your function. So you have to piece-meal your loop cycle even more, calling your function (acquire-release), then manually acquire the lock, do the extra work, and manually release it before the cycle ends. And you have absolutely no guarantee of what happens between your function releasing it and you acquiring it.

How to determine that multiple threads call function simultaneously in C?

I want to determine whether certain function in C can be called from multiple threads at the same time, in order to understand if I need to protect it with mutexes. The file where the function is implemented and defined does not have any mutex mechanism, so there is a chance that only one thread ever accesses the function but there is a chance that multiple threads do.
I thought to add a thread local storage variable which I increment upon starting the function and decrement upon exiting the function. If, after decrementing, the value of the variable is greater than 0, then multiple threads access the function.
This is my code:
#include <stdio.h>
static __thread int threadCounter = 0;
void f(void)
{
threadCounter++;
// do something
threadCounter--;
printf("threadCounter: %d\n", threadCounter);
}
a'm wondering if this solution is sufficient to determine whether multiple threads access a function and whether there are better ways to accomplish this.
From the GCC documentation :
"Thread-local storage (TLS) is a mechanism by which variables are allocated such that there is one instance of the variable per extant thread."
Thus, your solution will always indicate that only one thread access your function at the time even if it's not the case. You should use a variable that is shared between thread. But using a volatile one is still not a good solution because if there are multiple thread accessing it at the time, the value might not be the good one.
In conclusion, I think the better way of doing this would be to setup a mutex and using the pthread_mutex_trylock function to detect if there are multiple threads trying to call your function.
A thread local variable is by definition only visible for the current thread, your solution won't work. But your approach is good. Instead of using a thread local variable you should use a variable protected by a mutex.
This test either is using a local variable, or it isn't thread-safe in itself. In either case, it won't be useful as proof. If you want to use a counter, you have to protect it with something like a mutex or critical section. There's pretty much no way around this.
But there's a another way to do this better though, giving you exact information of who called the function, while at the same time not having to modify the actual function. You can create a "mock" function:
#define f() ( print(__func__), f() )
This prints the name of the thread callback function, then calls the actual function f(). This works because the pre-processor token f() is evaluated before any function call.
I wrote the function as a custom one print, since you'll still have the problem with multiple thread trying to access stdout at once if you use printf etc. So the custom print function must contain the means of thread-safety.

General Race Condition

I am new to C and wanted to know about race conditions. I found this on the internet and it asked to find the race condition, and a solution to it.
My analysis is that the race condition is in the create-thread() method has the race condition, specifically in the if-else statement. So when the method is being accessed another thread could be created or removed during the check-and-act and the thread_amt would be off.
In order to not have the race condition, then lock the if-else using mutex, semaphores, etc?
Can anyone correct me if I am wrong, and could possibly show me how to implement mutex?
#define MAXT 255
int threads_amt = 0;
int create-thread() // create a new thread
{
int tid;
if (threads_amt == MAXT) return -1;
else
{
threads_amt++;
return tid;
}
}
void release-thread()
{
/* release thread resources */
--threads_amt;
}
Yeah, the race condition in this case happens because you have no guarantee that the checking and the manipulation of threads_amt are going to happen with no interruption/execution of another thread.
Three solutions off the top of my head:
1) Force mutual exclusion to that part of code using a binary semaphore (or mutex) to protect the if-else part.
2) Use a semaphore with initial value MAXT, and then, upon calling create_thread (mind, you can't use hyphens in function names!), use "wait()" (depending on the type of semaphore, it could have different names (such as sem_wait())). After that, create the thread. When calling release_thread(), simply use "signal()" (sem_post(), when using semaphore.h).
3) This is more of an "hardware" solution: you could assume that you are given an atomic function that performs the entire if-else part, and therefore avoids any race condition problem.
Of these solutions, the "easiest" one (based on the code you already have) is the first one.
Let's use semaphore.h's semaphores:
#define MAXT 255
// Global semaphore
sem_t s;
int threads_amt = 0;
int main () {
...
sem_init (&s, 0, 1); // init semaphore (initial value = 1)
...
}
int create_thread() // create a new thread
{
int tid;
sem_wait(&s);
if (threads_amt == MAXT) {
sem_post(&s); // the semaphore is now available
return -1;
}
else
{
threads_amt++;
sem_post(&s); // the semaphore is now available
return tid;
}
}
void release_thread()
{
/* release thread resources */
sem_wait(&s);
--threads_amt;
sem_post(&s);
}
This should work just fine.
I hope it's clear. If it's not, I suggest that you study how semaphores work (use the web, or buy some Operating System book). Also, you mentioned that you are new to C: IMHO you should start with something easier than this: semaphores aren't exactly the next thing you want to learn after the 'hello world' ;-)
The race condition is not in the if() statements.
It is with access to the variable threads_amt that is potentially changed and accessed at the same time in multiple threads.
Essentially, any thread that modifies the variable must have exclusive access to avoid a race condition. That means all code which modifies the variable or reads its value must be synchronised (e.g. grab a mutex first, release after). Readers don't necessarily need exclusive access (e.g. two threads reading at the same time won't necessarily affect each other) but writers do (so avoid reading a value while trying to change it in another thread) - such considerations can be opportunities to use synchronisation methods other than a mutex - for example, semaphores.
To use a mutex, it is necessary to create it first (e.g. during project startup). Then grab it when needed, and remember to release it when done. Every function should minimise the time that it holds the mutex, since other threads trying to grab the mutex will be forced to wait.
The trick is to make the grabbing and releasing of the mutex unconditional, wherever it occurs (i.e. avoid a function that grabs the mutex, being able to return without releasing it). That depends on how you structure each function.
The actual code for implementing depends on which threading library you're using (so you need to read the documentation) but the concepts are the same. All threading libraries have functions for creating, grabbing (or entering), and releasing mutexes, semaphores, etc etc.

Multi threading and deadlock

I am making a multi-threaded C program which involves the sharing of a global dynamic integer array between two threads. One thread will keep adding elements to it & the other will independently scan the array & free the scanned elements.
can any one suggest me the way how can I do that because what I am doing is creating deadlock
Please also can any one provide the code for it or a way to resolve this deadlock with full explanation
For the threads I would use pthread. Compile it with -pthread.
#include <pthread.h>
int *array;
// return and argument should be `void *` for pthread
void *addfunction(void *p) {
// add to array
}
// same with this thread
void *scanfunction(void *p) {
// scan in array
}
int main(void) {
// pthread_t variable needed for pthread
pthread_t addfunction_t, scanfunction_t; // names are not important but use the same for pthread_create() and pthread_join()
// start the threads
pthread_create(&addfunction_t, NULL, addfunction, NULL); // the third argument is the function you want to call in this case addfunction()
pthread_create(&scanfunction_t, NULL, scanfunction, NULL); // same for scanfunction()
// wait until the threads are finish leave out to continue while threads are running
pthread_join(addfunction_t, NULL);
pthread_join(scanfunction_t, NULL);
// code after pthread_join will executed if threads aren't running anymore
}
Here is a good example/tutorial for pthread: *klick*
In cases like this, you need to look at the frequency and loading generated by each operation on the array. For instance, if the array is being scanned continually, but only added to once an hour, its worth while finding a really slow, latency-ridden write mechanism that eliminates the need for read locks. Locking up every access with a mutex would be very unsatisfactory in such a case.
Without details of the 'scan' operation, especially duration and frequency, it's not possible to suggest a thread communication strategy for good performance.
Anohter thing ee don't know are consequences of failure - it may not matter if a new addition is queued up for a while before actually being inserted, or it may.
If you want a 'Computer Science 101' answer with, quite possibly, very poor performance, lock up every access to the array with a mutex.
http://www.liblfds.org
Release 6 contains a lock-free queue.
Compiles out of the box for Windows and Linux.

Does a mutex guarantee visibility (GLib)?

I'm using Glib's mutex utilities to handle concurrency. Is it guaranteed that the updated version of a modified variable will be visible to any other thread after unlocking a mutex?
Do these threads have to acquire a lock on the mutex as well in order to read it safely?
GStaticMutex mutex;
int value;
void init() {
g_static_mutex_init(&mutex);
value = 0;
}
void changeValue() {
g_static_mutex_lock(&mutex);
value = generateRandomNumber();
g_static_mutex_unlock(&mutex);
}
You should work by the book, and let the smart people who implemented the mutex worry about visibility and barriers. The book says a mutex should be held both when reading and when writing.
The CPU can rearrange reads, and does this a lot. It helps reduce the penalty of cache misses, because you start to fetch the data a while before it's actually needed.
So if you read a variable after another CPU wrote it and released the lock, the read may actually be performed before these things happen.
The mutex serves as a memory barrier, preventing this problem (and others).
The mutex object should only be read through the g_static_mutex_* functions. If you want to know if you can acquire the mutex you can use this function:
g_static_mutex_trylock
On the linkage of the identifier, it follows the same rules as with any other C identifier: it depends in which scope it is declared and if some storage class specifier (e. g., static or extern) is specified.
I guess I found the answer. Gthread is a wrapper around pthread (according to http://redmine.lighttpd.net/boards/3/topics/425) and pthreads seem to implement a memory barrier (http://stackoverflow.com/questions/3208060/does-guarding-a-variable-with-a-pthread-mutex-guarantee-its-also-not-cached)
But I'm uncertain if it is necessary to use the mutex read the value.

Resources