Parallel processes using semaphores in C - c

I have a big problem with semaphores in C. Here is the link to inspiration of my code: http://cse.unl.edu/~ylu/csce351/notes/Solution%20for%20Building%20H2O.pdf.
There are two similar codes for hydrogen and oxygen. This is the idea: There are processes generated for oxygen and hydrogen and they are created in different time. When there are 2 hydrogens and 1 oxygen they call function bond(). But they have to wait for them. After the condition is evaluated as false it is supposed to switch to another process (or at least that is how I understand it). But in my code it continues to the next command which causes that it won't wait to all processes that I need. It prints to output after every process that is created even if it is supposed to wait. Does anyone know know whats wrong there?
(I can post more of the code if this is not enough.)
OXYGEN CODE:(hydrogen is similar)
sem_wait(mutex);
if ((*hydrogen >=2) && (*oxigen>=1))
{
(*count_c)++;
*count_cur_h-=2;
sem_post(hydrel);
sem_post(hydrel);
*count_cur_o-=1;
sem_post(oxrel);
}
else
{
(*count_c)++;
sem_post(mutex); // This is the place where it is supposed
// to release and continue to another process,
// but it goes to the next command.
}
sem_wait(oxrel);
bond();
sem_wait(barrier);
//semaphores are initialized like this:
sem_init(mutex,1,1);
sem_init(oxrel,1,1);
sem_init(hydrel,1,2);
sem_init(barrier,1,3);

sem_post is not a blocking call. sem_wait is the blocking call. If the value of semaphore is zero when sem_wait is called, the function that called it will block. sem_post is used to release another thread that is blocking waiting on sem_wait when the semaphore value is zero, but it does not block itself. The sem_post call is used to 'wake up a thread waiting on sem-wait' but then continues onwards, and both threads will then run at the same time (if you have at least 2 logical CPUs). If you want the thread that called sem_post to block at that point you will need to do something else (like add yet another semaphore).

Related

How to properly synchronize threads at barriers

I am encountering an issue where I have a hard time telling which synchronization primitive I should use.
I am creating n parallel threads that work on a region of memory, each is assigned to a specific part of this region and can accomplish its task independently from the other ones. At some point tho I need to collect the result of the work of all the threads, which is a good case for using barriers, this is what I'm doing.
I must use one of the n worker threads to collect the result of all their work, for this I have the following code that follows the computation code in my thread function:
if (pthread_barrier_wait(thread_args->barrier)) {
// Only gets called on the last thread that goes through the barrier
// This is where I want to collect the results of the worker threads
}
So far so good, but now is where I get stuck: the code above is in a loop as I want the threads to accomplish work again for a certain number of loop spins. The idea is that each time pthread_barrier_wait unblocks it means all threads have finished their work and the next iteration of the loop / parallel work can start again.
The problem with this is that the result collector block statements are not guaranteed to execute before other threads start working on this region again, so there is a race condition. I am thinking of using a UNIX condition variable like this:
// This code is placed in the thread entry point function, inside
// a loop that also contains the code doing the parallel
// processing code.
if (pthread_barrier_wait(thread_args->barrier)) {
// We lock the mutex
pthread_mutex_lock(thread_args->mutex);
collectAllWork(); // We process the work from all threads
// Set ready to 1
thread_args->ready = 1;
// We broadcast the condition variable and check it was successful
if (pthread_cond_broadcast(thread_args->cond)) {
printf("Error while broadcasting\n");
exit(1);
}
// We unlock the mutex
pthread_mutex_unlock(thread_args->mutex);
} else {
// Wait until the other thread has finished its work so
// we can start working again
pthread_mutex_lock(thread_args->mutex);
while (thread_args->ready == 0) {
pthread_cond_wait(thread_args->cond, thread_args->mutex);
}
pthread_mutex_unlock(thread_args->mutex);
}
There is multiple issues with this:
For some reason pthread_cond_broadcast never unlocks any other thread waiting on pthread_cond_wait, I have no idea why.
What happens if a thread pthread_cond_waits after the collector thread has broadcasted? I believe while (thread_args->ready == 0) and thread_args->ready = 1 prevents this, but then see next point...
On the next loop spin, ready will still be set to 1 hence no thread will call pthread_cond_wait again. I don't see any place where to properly set ready back to 0: if I do it in the else block after pthread_cond_wait, there is the possibility that another thread that wasn't cond waiting yet reads 1 and starts waiting even if I already broadcasted from the if block.
Note I am required to use barriers for this.
How can I solve this issue?
You could use two barriers (work and collector):
while (true) {
//do work
//every thread waits until the last thread has finished its work
if (pthread_barrier_wait(thread_args->work_barrier)) {
//only one gets through, then does the collecting
collectAllWork();
}
//every thread will wait until the collector has reached this point
pthread_barrier_wait(thread_args->collect_barrier);
}
You could use a kind of double buffering.
Each worker would have two storage slots for results.
Between the barriers the workers would store their results to one slot while the collector would read results from the other slot.
This approach has a few advantages:
no extra barriers
no condition queues
no locking
slot identifier does not even have to be atomic because each thread could have it's own copy of it and toggle it whenever reaching a barrier
much more performant as workers can work when collector is processing the other slot
Exemplary workflow:
Iteration 1.
workers write to slot 0
collector does nothing because no data is ready
all wait for barrier
Iteration 2.
worker write to slot 1
collector reads from slot 0
all wait for barrier
Iteration 3.
workers write to slot 0
collector reads from slot 1
all wait for barrier
Iteration 4.
go to iteration 2

Why is there a while loop in wait function of a semaphore, when if can be used too?

this is my code:
wait(){
while(S<=0)
//puts the thread in the block list until it wakes up(by calling post)
S = S-1
}
there is a while loop in the wait function of a semaphore, can't I use an if statement simply?
Because we can't assume that after a thread is woken up and it requires the lock another thread has not already come along and taken the resource this is guarding:
wait(){
Some lock_guard(mutex); // You lock here.
while(S<=0) {
condition.wait(lock_guard); // While you wait here
// the lock is released.
// when the condition/semaphore is signalled
// one or more threads may be released
// but they must aquire the lock before
// they return from wait.
//
// Another thread may enter this function
// aquire the lock and decrement S below
// before the waiting thread aquires the
// lock and thus mustbe resuspended.
}
S = S-1
}
Why is there a while loop in wait function of a semaphore, when if can be used too?
I take the
//puts the thread in the block list until it wakes up(by calling post)
comment as a place-holder for code that really does do what the comment describes, and the code overall to be meant as schematic for an implementation of a semaphore (else there is no semaphore to be found in it, and the [linux-kernel] tag also inclines me in this direction). In that event ...
Consider the case that two threads are blocked trying to decrement the semaphore. A third thread increments the semaphore to value 1, causing both of the first two to unblock. Only one of erstwhile-blocked threads can be allowed to decrement the semaphore at that point, else its value would drop below zero. The other needs to detect that it cannot proceed after all, and go back to waiting. That's what the loop accomplishes.
What you have here is called active waiting. Thread or process waits for variable S to change it value to 1 in order to access critical section. One IF would only check once and then go to futher instruction (in this case instruction from critical section, which would be huge error). Thats why it should wait in loop - in order to actually wait, not only check condition once.
But your code is not doing what you think it does.
while(S == 0) {}
or
while(S == 0);
would do the work. Your code constantly does S = S - 1 and with your condition it creates infinite loop. S in semaphores should never go lower than 0, as it would mean that one thread went to critical section without permisson.

Correct way to unblock a kernel thread

There are linux kernel threads that do some work every now and then, then either go to sleep or block on a semaphore. They can be in this state for several seconds - quite a long time for a thread.
If threads need to be stopped for some reason, at least if unloading the driver they belong to, I am looking for a way to get them out of sleep or out of the semaphore without waiting the whole sleep time or triggering the semaphore as often as required.
I found and read a lot about this but there are multiple advises and I am still not sure how things work. So if you could shed some light on that.
msleep_interruptible
What is able to interrupt that?
down_interruptible
This semaphore function implies interrupt-ability. Same here, what can interrupt this semaphore?
kthread_stop
It's described as sets kthread_should_stop to true and wakes it... but this function blocks until the sleep time is over (even if using msleep_interruptible) or the semaphore is triggered.
What am I understanding wrong?
Use a signal to unblock - really?
My search found a signal can interrupt the thread. Other hits say a signal is not the best way to operate on threads.
If a signal is the best choice - which signal do I use to unblock the thread but not mess it up too much?
SIGINT is a termination signal - I don't intend to terminate something, just make it go on.
More information
The threads run a loop that checks a termination flag, does some work and then block in a sleep or a semaphore. They are used for
Situation 1.
A producer-consumer scenario that uses semaphores to synchronize producer and consumer. They work perfectly to make threads wait for work and start running on setting the semaphore.
Currently I'm setting a termination flag, then setting the semaphore up. This unblocks the thread which then checks the flag and terminates. This isn't my major problem. Hovever of course I'd like to know about a better way.
Code sample
while (keep_running) {
do_your_work();
down_interruptible(&mysemaphore); // Intention: break out of this
}
Situation 2.
A thread that periodically logs things. This thread sleeps some seconds between doing it's work. After setting the flag this thread terminates at it's next run but this can take several seconds. I want to break the sleep if necessary.
Code sample
while (keep_running) {
do_your_work();
msleep(15000); // Intention: break out of this - msleep_interruptible?
}

halting a client server program

I am sorry for the basicness of this question, but I am having an issue here. I have a client-server program. I don't know before hand how many connections will come but they are not infinite. And at the end , after all connections are closed some results are output. But the problem I am having is, accepting connections is in an infinite while loop, how is it stoppedd to output the result.
Thanks
you need to have some form of condition to break out of you loop, in your case, a timeout would probably work the best, basically meaning, if you don't get any new clients for x seconds, you stop looking for clients, same goes for any for of connection error.
Anything more requires looking at the code you are using.
Handling EINTR on error from accept(2) with terminating the program and hitting ^C usually works.
You could install a handler for the SIGTERM signal which would set a global volatile sig_atomic_t variable, and test that variable in your multiplexing loop (probably around poll or select). Remember that signal handlers cannot call many functions (only the async-signal-safe ones).
Catching nicely SIGTERM is expected from most Linux or Posix servers.
You could consider using an event handling library like libev, libevent etc.
Although my background is with Windows NT the function "names" are ones that name generic threading or process functions that should be available in any multi-threading environment.
If the main thread can determine when the child thread in question should terminate it can either do this by having the child thread loop on a boolean - such as "terminate_conditon" - or by terminating the thread throught its handle.
// child thread
terminate_condition=FALSE;
while (!terminate_condition)
{
// accept connections
}
child_thread_done=TRUE;
// output results
exit_thread ();
// main thread
child_thread_done=FALSE;
child_thread=create_thread (...);
// monitor connections to determine when done
terminate_condition=TRUE;
while (!child_thread_done)
{
sleep (1);
}
// or maybe output results here?
exit_process ();
This controlled termination solution requires that only one thread writes to the child_thread_done boolean and that any other thread only reads.
Or
// child thread
while (1)
{
// accept connections
}
// main thread
child_thread=create_thread (...);
// monitor connections to determine when done
kill_thread (child_thread);
// output results
exit_process ();
The second form is messier since it simply kills the child thread. In general it is better to have the child thread perform a controlled termination, especially if it has allocated resources (which become the responsibility of the process as a whole rather than just the allocating thread).
If there are many child threads working with connections a synchronized termination mechanism is necessary: either a struct with as many members as there are child threads (a terminating thread sets its "terminated" boolean to true, terminates and the main thread monitors the struct to make sure all child "terminated" booleans are true before proceeding) or a counter containing the number of child threads operating (when a child is about to terminate it takes exclusive control of the counter via a spinlock, decrements it and frees the lock before terminating: the main thread doesn't do anything before the counter contains zero).

For pthread, How to kill child thread from the main thread

I use pthread_create to create several child threads. At a time, the main thread wants to kill all child threads or there will be segment falut. Which function should I use to finish that? I searched the answer from google and got function like pthread_kill. But I did not know which signal should I send to the child thread to kill them. My running environment is RHEL 5.4 and programming language is C.
In general, you don't really want to violently kill a child thread, but instead you want to ask it to terminate. That way you can be sure that the child is quitting at a safe spot and all its resources are cleaned up.
I generally do this with a small piece of shared state between parent and child to allow the parent to communicate a "quit request" to each child. This can just be a boolean value for each child, protected by a mutex. The child checks this value periodically (every loop iteration, or whatever convenient checkpoints you have in your child thread). Upon seeing "quit_request" being true, the child thread cleans up and calls pthread_exit.
On the parent side, the "kill_child" routine looks something like this:
acquire shared mutex
set quit_request to true
pthread_join the child
The pthread_join may take some time, depending on how frequently the child checks its quit request. Make sure your design can handle whatever the delay may be.
It is possible to "cancel" a thread using pthread_cancel. However, this isn't typically best practice though under extreme circumstances like a SEGFAULT it may be conisdered a reasonable approach.
You should send SIG_TERM to each of your threads, using
int pthread_kill(pthread_t thread, int sig);
A quick way to get rid of all threads (besides the main) is to fork() and keep going with the child.
Not hyper clean...
if (fork()) exit(0); // deals also with -1...
You can use a global variable for the entire program.
int _fCloseThreads;
Set it to 1 when you want the threads to quit execution. Have the threads check that variable in their "loop" and nicely quit when it is set to 1. No need to protect it with a mutex.
You need to wait for the threads to quit. You can use join. Another way is to increment a counter when a thread enters its thread proc and then decriment the counter when it exits. The counter would need to be a global of sorts. Use gcc atomic ops on the counter. The main thread, after setting fCloseThreads, can wait on the counter to go to zero by looping, sleeping, and checking the count.
Finally, you might checkout pthread_cleanup_push and pop. They are a model for allowing a thread to cancel anywhere in its code (uses a longjump) and then call a final cleanup function before exiting threadproc. You basicly put cleanup_push at the top of your threadproc and cleanup_pop at the bottom, create an unwind function, and then at certain cancelation points a thread canceled by a call to pthread_cancel() will longjump back to threadproc and call the unwind function.

Resources