Synchronizing threads, mutex - c

I'm trying to do my homework but I'm stuck with these threads.. This function is called when a thread is created:
size_t* mines, gold = 0, gold_collected = 0;
pthread_mutex_t mine_mutex;
int last_mine = 0;
void* dig(void *mine_start) {
int current_worker = (int)mine_start;
int mine = (int)mine_start;
// printf("Hello, it's me, thread %d\n", current_worker);
while(gold != 0) {
if(mine > last_mine - 1) {
mine = 0;
}
pthread_mutex_lock(&mine_mutex);
if(mines[mine] != 0) {
//printf("All gold %zd\n", gold);
//printf("Gold in mine %zd with number %d\n", mines[mine], mine);
printf("Worker %d entered mine %d\n", current_worker, mine);
gold -= 10;
mines[mine] -= 10;
gold_collected += 10;
//sleep(1);
}
pthread_mutex_unlock(&mine_mutex);
++mine;
}
pthread_exit(NULL);
}
My problem is that when I have 5 mines and 2 workers, only one worker gets in the mine and digs the gold. How can I rotate my threads so all of them can dig from the mine?

If you want 1 miner per mine, but you have more miners than mines, then you have to decide what the idle miners will do when all the mines are in use. Furthermore, if you have a mutex per mine, and everyone tries to take the first mutex, only one miner will win, and the others will still block. You can use a try lock, but then the miners will busy wait when all the mines are full.
You could use a semaphore that is initialized with the number of mines. Each miner, upon successfully acquiring the semaphore would know that there is a mine available for them, but they wouldn't know which one. You could use a single mutex to protect all of the mines' in-use state. After acquiring the semaphore, you then acquire the mutex, hunt for an available mine, mark it as in-use, release the mutex and start mining. Then, when you are done, re-acquire the mutex, mark the mine as available, release the mutex, and then release the semaphore.
Finally, instead of the semaphore, you could use a condition variable and a mutex. Acquire the mutex, and hunt for an available mine. If you cannot find one, block on the condvar. If you do find one, mark it as in use, release the mutex, and start mining. When you are done, re-acquire the mutex, mark the mine as available, signal the condvar, and release the mutex. A thread that awakes on the condvar will have automatically re-acquired the mutex and should loop around and re-hunt for an available mine. In this case, it should be sufficient to signal the condvar instead of broadcasting; although broadcasting can be safer.
Also, once you have parallel miners, you're going to have to rethink the global gold and gold_collected. Since your miners will be doing the actual mining without holding a mutex, they cannot update these globals while mining. They should keep a local tally of the amount of gold they mined, and update the global once the mutex has been re-acquired. Maybe gold can be deducted before the miner enters the mine, and gold_collected updated after leaving the mine (both while holding the mutex). It's also a little iffy reading gold when not holding the mutex, since it could change underneath you...

There is only one mutex for both mines, so only one worker can be working in the mines. If you have one mutex per mine, then two workers can enter in mines at same time (one worker in each mine).

Related

(C) Dining Philosophers - How to make concurrent threads wait till a condition is satisfied?

I am a beginner and I was implementing Dining Philosopher's problem. However, I ran across an issue. In my philosopher() function, I want my other threads to wait till the right and left chopsticks are available for them to use. How should I implement this? Currently, the program simply terminates after 2 philosophers are done eating without waiting for the others to eat
I've already tried :
Using mutex to lock the shared variables in the philosopher() function and although it makes sure that no philosopher goes hungry, using this approach means giving up concurrency (only one philosopher can eat at a time even though there are chopsticks available for other philosophers to use)
Using sleep() function in my while-loop but it doesn't work either
Any help is appreciated, thanks!
CODE
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <stdlib.h>
#define NUM 5 // Number of Philosophers
sem_t chopSticks[NUM]; // binary semaphore for each chopstick
sem_t mutex;
int philNo[NUM] = {0, 1, 2, 3, 4};
void* philosopher(void*);
int main()
{
int semValue;
pthread_t threadId[NUM]; // 5 concurrent threads for 5 philsophers
sem_init(&mutex, 0, 1);
for(int i=0; i< NUM; i++)
sem_init(&chopSticks[i], 0, 1);
for(int i=0; i< NUM; i++)
{
pthread_create(&threadId[i], NULL, philosopher, (void*) &philNo[i]);
printf("\nPhilosopher %d is thinking", i+1);
}
for(int i=0; i< NUM; i++)
pthread_join(threadId[i], NULL);
return 0;
}
void* philosopher(void* philNo)
{
int n = *(int*) philNo;
int rightValue, leftValue;
int left = (n+4) % NUM;
int right = (n+1) % NUM;
sem_getvalue(&chopSticks[left], &leftValue);
sem_getvalue(&chopSticks[right], &rightValue);
//sem_wait(&mutex);
/* while(leftValue != 1 && rightValue != 1)
{
wait for the left and right chopsticks to be free
How should I implement this?
} */
if(leftValue == 1 && rightValue == 1) // if both left and right chopSticks are free then start eating
{
sem_wait(&chopSticks[left]);
sem_wait(&chopSticks[right]);
printf("\nPhilosopher %d has taken Chopstick-%d and Chopstick-%d", n+1, left+1, right+1);
printf("\nPhilosopher %d is Eating", n+1);
sleep(1);
sem_post(&chopSticks[left]);
sem_post(&chopSticks[right]);
printf("\nPhilosopher %d finished eating", n+1);
printf("\nPhilosopher %d has put down chopstick-%d and chopstick-%d", n+1, left+1, right+1);
}
//sem_post(&mutex);
}
You can not have sempahore per fork on the dining table. This is the classic mistake that will lead you to the deadlock situation.
Imagine all the philosophers simultaneously pick up the left fork your sempahore implementation will allow that, but after that point no one will be able to pick up the right fork, because none is available and all threads will indefinitely block.
The only solution that will work is a philosopher will not pickup any fork till both the left & right hand forks are available (i.e. neither neighbor is eating at the same time.)
The philosopher’s routine is:
0. Each philosopher will have state associated with her. The state is referred by the neighbours to find out what the philosopher is doing.
Spend time thinking. State of the philosopher is THINKING.
Philosopher becomes hungry, state of the philosopher is HUNGRY.
Check if you can pickup the left fork and right fork. (i.e. make sure left neighbour & right neighbour’s state is not EATING.) If either of fork is not available block till they become available.
When both forks are available change state to EATING, pickup the forks and start eating.
When your eating is done. Put down the left fork, check if your left neighbour is blocked for the fork you’re putting down, if she is wake her up to start eating. Then put down the right fork, check if your right neighbour is blocked for the fork you’re putting down, if she is wake her up to start eating.
Goto step 1.
Pseudo oop code is as below:
#define N 5
#define LEFT(i) (i-1)%N
#define RIGHT(i) (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2
class DinningPhilosopher {
public:
DinningPhilosopher();
~DinningPhilosopher();
void
philosopherRoutine(
IN byte i
);
private:
byte m_state[N];
Semaphore *m_sem[N];
Mutex *m_mutex;
void
takeForks(
IN byte i
);
void
putForks(
IN byte i
);
void
testForkAvailability(
IN byte i
);
};
DinningPhilosopher::DinningPhilosopher()
{
// All philosopher's are thinking initially.
for (int i=0; i<N; i++) {
m_state[i] = THINKING;
}
for (int i=0; i<N; i++) {
m_sem[i] = new Semaphore(0);
}
m_mutex = new Mutex();
}
// N threads will be spawned, one for each philosopher.
// Argument i is philosopher id between (0,N)
void
DinningPhilosopher::philosopherRoutine(
IN byte i
)
{
while(true) {
continueThinking();
takeForks(i);
continueEating();
putForks(i);
}
}
void
DinningPhilosopher::takeForks(
IN byte i
)
{
m_mutex->lock();
// Announce to neighbours you're HUNGRY.
m_state[i] = HUNGRY;
// Test if left fork & right forks are available.
// If available announce neighbours you're EATING.
// so they don't pick up forks you already claimed.
testForkAvailability(i);
m_mutex->unlock();
// If you are not yet EATING,
// block till required forks are available.
// Section A.
m_sem[i]->wait();
}
void
DinningPhilosopher::testForkAvailability(
IN byte i
)
{
// Note that m_mutex was locked before calling this function
// Thread has exclusive access to execute this function.
if (m_state[LEFT(i)] != EATING && // your left fork is available
m_state[RIGHT(i)] != EATING && // your right fork is available
m_state[i] == HUNGRY // and you want to start eating.
) {
// Announce neighbours you started eating.
m_state[i] = EATING;
// Fork availability is passed.
// Make sure you're not blocked at "Section A"
// in function takeForks()
m_sem[i]->post();
}
}
void
DinningPhilosopher::putForks(
IN byte i
)
{
m_mutex->lock();
// Announce to neighbours you're done EATING.
m_state[i] = THINKING;
// Put down the left fork,
// If your left neighbour is blocked at "Section A"
// of function takeForks().
// Allow him to unblock to start eating.
testAvailability(LEFT(i));
// Put down the right fork.
testAvailability(RIGHT(i));
m_mutex->unlock();
}
Check out link below:
https://codeistry.wordpress.com/2018/04/06/dinning-philosophers-problem/
I am a beginner and I was implementing Dining Philosopher's problem.
However, I ran across an issue. In my philosopher() function, I want
my other threads to wait till the right and left chopsticks are
available for them to use. How should I implement this?
I've already tried :
Using mutex to lock the shared variables in the philosopher() function and although it makes sure that no philosopher goes hungry,
using this approach means giving up concurrency (only one philosopher
can eat at a time even though there are chopsticks available for other
philosophers to use)
You absolutely do need at least one mutex or similar synchronization object, because your threads need to access shared data (the states of the chopsticks, or an equivalent). Shared data must be accessed only in a critical section protected by an appropriate synchronization object.
However, you don't necessarily need to hold the mutex locked between such accesses, and often you want to avoid doing so, in order that other threads will have the chance to run.
Using sleep() function in my while-loop but it doesn't work either
As I wrote in comments, sleep() is not a synchronization function. It might have a role to play in a solution, but not in inter-thread activities.
The key thing to recognize for the dining philosophers problem is that if you want philosophers eating concurrently without having to orchestrate the whole meal in detail, then each philosopher must be able to try multiple times to pick up chopsticks until they succeed, without preventing any other philosophers from eating in the meantime.
Additionally, it is counterproductive for a thread to just try over and over when it has no reason to think that anything has changed since its last attempt.
When a thread needs to wait to proceed until some data-dependent condition is satisfied, you should immediately consider using a condition variable. Sometimes there are reasonable alternatives, but condition variables are the Swiss army knife for these situations.
Condition variables are used together with mutexes -- a mutex is used to protect the non-atomic variables by which each thread will determine whether it can proceed, and if the thread determines that it must wait, the CV assists it in both allowing other threads to lock the mutex while it waits, and in receiving notification that it should check again. This should always be performed in a loop because the thread might determine after waking that conditions still aren't right for it to move forward.
There are several ways to implement that in the Dining Philosophers problem. You could use a separate condition variable for each chopstick, all with the same mutex, but it would be simpler to use just one mutex and one CV:
When one of the philosophers decides that he is ready to eat, he locks the mutex, and checks whether both the chopsticks he needs are available.
If so, he picks them up, releases the mutex, and proceeds to eat.
If not, then he waits for the condition variable to be signaled by another thread. The mutex is automatically released during this wait, and regained before the thread resumes from it. When the thread resumes, it loops back to check the chopsticks again.
For example (error checking elided for clarity):
pthread_mutex_lock(&mutex);
while(chopsticks[left] || chopsticks[right]) {
pthread_cond_wait(&cv, &mutex);
}
chopsticks[left] = 1;
chopsticks[right] = 1;
pthread_mutex_unlock(&mutex);
When the philosopher is done eating, he locks the mutex, puts down the chopsticks, releases the mutex, and then signals all the threads waiting on the CV, so that they will check again whether they can proceed.
For example:
pthread_mutex_lock(&mutex);
chopsticks[left] = 0;
chopsticks[right] = 0;
pthread_mutex_unlock(&mutex);
pthread_cond_broadcast(&cv);
Note also that since the chopstick states are being protected via a mutex, there is no advantage to using semaphores to model them. The example code above assumes an ordinary array of _Bool or some other integer type, initialized with all zeroes.

Only one thread ever acquiring semaphore

I have a program in which multiple threads are in a loop where they acquire a binary semaphore and then increase a global counter. However, by printing out the thread IDs, I notice that only one thread ever acquires the semaphore. Here's my MRE:
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_THREADS 10
#define MAX_COUNTER 100
struct threadCtx {
sem_t sem;
unsigned int counter;
};
static void *
threadFunc(void *args)
{
struct threadCtx *ctx = args;
pthread_t self;
bool done = false;
self = pthread_self();
while (!done) {
sem_wait(&ctx->sem);
if ( ctx->counter == MAX_COUNTER ) {
done = true;
}
else {
sleep(1);
printf("Thread %u increasing the counter to %u\n", (unsigned int)self, ++ctx->counter);
}
sem_post(&ctx->sem);
}
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
struct threadCtx ctx = {.counter = 0};
sem_init(&sem.ctx, 0, 1);
for (int k=0; k<NUM_THREADS; k++) {
pthread_create(threads+k, NULL, threadFunc, &ctx);
}
for (int k=0; k<NUM_THREADS; k++) {
pthread_join(threads[k], NULL);
}
sem_destroy(&ctx.sem);
return 0;
}
The output is
Thread 1004766976 increasing the counter to 1
Thread 1004766976 increasing the counter to 2
Thread 1004766976 increasing the counter to 3
...
If I remove the call to sleep, the behavior is closer to what I would expect (i.e., the threads being woken up in a seemingly indeterminate manner). Why would this be?
David Schwartz's answer explains what is happening at a low level. That is to say, he's looking at it from the perspective of an OS developer or a hardware designer. Nothing wrong with that, but let's look at your program from the perspective of a Software Architect:
You've got multiple threads all executing the same loop. The loop locks the mutex,* it does some "work," and then it releases the mutex. OK, but what does it do next? Almost the very next thing that your loop does after releasing the mutex is it locks the mutex again. Your loop spends practically 100% of its time doing "work" with the mutex locked.
So, what's the point of running that same loop in multiple threads when there's never any opportunity for two or more threads to work at the same time?
If you want to use threads to do a parallel computation, you need to find/invent safe ways for the threads to do most of their work with the mutex unlocked. They should only lock a mutex for just long enough to post a result or, to take another assignment.
Sometimes that means writing code that is less efficient than single threaded code would be. But suppose that program (A) has a single thread that makes almost 100% use of a CPU, while program (B) uses eight CPUs but only uses them with 50% efficiency. Which program is going to win?
* I know, your example uses a sem_t (semaphore) object. But "semaphore" is what you are using. "Mutex" is the role in which you are using it.
Why would this be?
Context switches are expensive and your implementation is, wisely, minimizing them. Your threads are all fighting over the same resource, trying to schedule them closely will make performance much worse, probably for the entire system.
Since the thread that keeps getting the semaphore never uses up its timeslice, it will keep getting the resource. It is your responsibility to write code to do the work that you want done. It's the implementation's responsibility to execute your code as efficiently as it can, and that's what it's doing.
Most likely, what's going under the hood is this:
The thread that keeps getting the sempahore can always make forward progress except when it is sleeping. But when it is sleeping, no other thread that needs the sempahore can make forward progress.
The thread that keeps getting the semaphore never exhausts its timeslice because it sleeps before that happens.
So there is no reason for the implementation to ever block this thread other than when it is sleeping, meaning that no other thread can get the semaphore. If you don't want this thread to keep sleeping with the semaphore and blocking other threads, then write different code.

Multi-threads program architecture C pthread

I'd like to create multi-threads program in C (Linux) with:
Infinite loop with infinite number of tasks
One thread per one task
Limit the total number of threads, so if for instance total threads number is more then MAX_THREADS_NUMBER, do sleep(), until total threads number become less then MAX_THREADS_NUMBER, continue after.
Resume: I need to do infinite number of tasks(one task per one thread) and I'd like to know how to implement it using pthreads in C.
Here is my code:
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_THREADS 50
pthread_t thread[MAX_THREADS];
int counter;
pthread_mutex_t lock;
void* doSomeThing(void *arg)
{
pthread_mutex_lock(&lock);
counter += 1;
printf("Job %d started\n", counter);
pthread_mutex_unlock(&lock);
return NULL;
}
int main(void)
{
int i = 0;
int ret;
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init failed\n");
return 1;
}
for (i = 0; i < MAX_THREADS; i++) {
ret = pthread_create(&(thread[i]), NULL, &doSomeThing, NULL);
if (ret != 0)
printf("\ncan't create thread :[%s]", strerror(ret));
}
// Wait all threads to finish
for (i = 0; i < MAX_THREADS; i++) {
pthread_join(thread[i], NULL);
}
pthread_mutex_destroy(&lock);
return 0;
}
How to make this loop infinite?
for (i = 0; i < MAX_THREADS; i++) {
ret = pthread_create(&(thread[i]), NULL, &doSomeThing, NULL);
if (ret != 0)
printf("\ncan't create thread :[%s]", strerror(ret));
}
I need something like this:
while (1) {
if (thread_number > MAX_THREADS_NUMBER)
sleep(1);
ret = pthread_create(...);
if (ret != 0)
printf("\ncan't create thread :[%s]", strerror(ret));
}
Your current program is based on a simple dispatch design: the initial thread creates worker threads, assigning each one a task to perform. Your question is, how you make this work for any number of tasks, any number of worker threads. The answer is, you don't: your chosen design makes such a modification basically impossible.
Even if I were to answer your stated questions, it would not make the program behave the way you'd like. It might work after a fashion, but it'd be like a bicycle with square wheels: not very practical, nor robust -- not even fun after you stop laughing at how silly it looks.
The solution, as I wrote in a comment to the original question, is to change the underlying design: from a simple dispatch to a thread pool approach.
Implementing a thread pool requires two things: First, is to change your viewpoint from starting a thread and having it perform a task, to each thread in the "pool" grabbing a task to perform, and returning to the "pool" after they have performed it. Understanding this is the hard part. The second part, implementing a way for each thread to grab a new task, is simple: this typically centers around a data structure, protected with locks of some sort. The exact data structure does depend on what the actual work to do is, however.
Let's assume you wanted to parallelize the calculation of the Mandelbrot set (or rather, the escape time, or the number of iterations needed before a point can be ruled to be outside the set; the Wikipedia page contains pseudocode for exactly this). This is one of the "embarrassingly parallel" problems; those where the sub-problems (here, each point) can be solved without any dependencies.
Here's how I'd do the core of the thread pool in this case. First, the escape time or iteration count needs to be recorded for each point. Let's say we use an unsigned int for this. We also need the number of points (it is a 2D array), a way to calculate the complex number that corresponds to each point, plus some way to know which points have either been computed, or are being computed. Plus mutually exclusive locking, so that only one thread will modify the data structure at once. So:
typedef struct {
int x_size, y_size;
size_t stride;
double r_0, i_0;
double r_dx, i_dx;
double r_dy, i_dy;
unsigned int *iterations;
sem_t done;
pthread_mutex_t mutex;
int x, y;
} fractal_work;
When an instance of fractal_work is constructed, x_size and y_size are the number of columns and rows in the iterations map. The number of iterations (or escape time) for point x,y is stored in iterations[x+y*stride]. The real part of the complex coordinate for that point is r_0 + x*r_dx + y*r_dy, and imaginary part is i_0 + x*i_dx + y*i_dy (which allows you to scale and rotate the fractal freely).
When a thread grabs the next available point, it first locks the mutex, and copies the x and y values (for itself to work on). Then, it increases x. If x >= x_size, it resets x to zero, and increases y. Finally, it unlocks the mutex, and calculates the escape time for that point.
However, if x == 0 && y >= y_size, the thread posts on the done semaphore and exits, letting the initial thread know that the fractal is complete. (The initial thread just needs to call sem_wait() once for each thread it created.)
The thread worker function is then something like the following:
void *fractal_worker(void *data)
{
fractal_work *const work = (fractal_work *)data;
int x, y;
while (1) {
pthread_mutex_lock(&(work->mutex));
/* No more work to do? */
if (work->x == 0 && work->y >= work->y_size) {
sem_post(&(work->done));
pthread_mutex_unlock(&(work->mutex));
return NULL;
}
/* Grab this task (point), advance to next. */
x = work->x;
y = work->y;
if (++(work->x) >= work->x_size) {
work->x = 0;
++(work->y);
}
pthread_mutex_unlock(&(work->mutex));
/* z.r = work->r_0 + (double)x * work->r_dx + (double)y * work->r_dy;
z.i = work->i_0 + (double)x * work->i_dx + (double)y * work->i_dy;
TODO: implement the fractal iteration,
and count the iterations (say, n)
save the escape time (number of iterations)
in the work->iterations array; e.g.
work->iterations[(size_t)x + work->stride*(size_t)y] = n;
*/
}
}
The program first creates the fractal_work data structure for the worker threads to work on, initializes it, then creates some number of threads giving each thread the address of that fractal_work structure. It can then call fractal_worker() itself too, to "join the thread pool". (This pool automatically "drains", i.e. threads will return/exit, when all points in the fractal are done.)
Finally, the main thread calls sem_wait() on the done semaphore, as many times as it created worker threads, to ensure all the work is done.
The exact fields in the fractal_work structure above do not matter. However, it is at the very core of the thread pool. Typically, there is at least one mutex or rwlock protecting the work details, so that each worker thread gets unique work details, as well as some kind of flag or condition variable or semaphore to let the original thread know that the task is now complete.
In a multithreaded server, there is usually only one instance of the structure (or variables) describing the work queue. It may even contain things like minimum and maximum number of threads, allowing the worker threads to control their own number to dynamically respond to the amount of work available. This sounds magical, but is actually simple to implement: when a thread has completed its work, or is woken up in the pool with no work, and is holding the mutex, it first examines how many queued jobs there are, and what the current number of worker threads is. If there are more than the minimum number of threads, and no work to do, the thread reduces the number of threads, and exits. If there are less than the maximum number of threads, and there is a lot of work to do, the thread first creates a new thread, then grabs the next task to work on. (Yes, any thread can create new threads into the process. They are all on equal footing, too.)
A lot of the code in a practical multithreaded application using one or more thread pools to do work, is some sort of bookkeeping. Thread pool approaches very much concentrates on the data, and the computation needed to be performed on the data. I'm sure there are much better examples of thread pools out there somewhere; the hard part is to think of a good task for the application to perform, as the data structures are so task-dependent, and many computations are so simple that parallelizing them makes no sense (since creating new threads does have a small computational cost, it'd be silly to waste time creating threads when a single thread does the same work in the same or less time).
Many tasks that benefit from parallelization, on the other hand, require information to be shared between workers, and that requires a lot of thinking to implement correctly. (For example, although solutions exist for parallelizing molecular dynamics simulations efficiently, most simulators still calculate and exchange data in separate steps, rather than at the same time. It's just that hard to do right, you see.)
All this means that you cannot expect to be able to write the code, unless you understand the concept. Indeed, truly understanding the concepts are the hard part: writing the code is comparatively easy.
Even in the above example, there are certain tripping points: Does the order of posting the semaphore and releasing the mutex matter? (Well, it depends on what the thread that is waiting for the fractal to complete does -- and indeed, if it is waiting yet.) If it was a condition variable instead of a semaphore, it would be essential that the thread that is interested in the fractal completion is waiting on the condition variable, otherwise it would miss the signal/broadcast. (This is also why I used a semaphore.)

Rerunning cancelled pthread

My problem is that I cannot reuse cancelled pthread. Sample code:
#include <pthread.h>
pthread_t alg;
pthread_t stop_alg;
int thread_available;
void *stopAlgorithm() {
while (1) {
sleep(6);
if (thread_available == 1) {
pthread_cancel(alg);
printf("Now it's dead!\n");
thread_available = 0;
}
}
}
void *algorithm() {
while (1) {
printf("I'm here\n");
}
}
int main() {
thread_available = 0;
pthread_create(&stop_alg, NULL, stopAlgorithm, 0);
while (1) {
sleep(1);
if (thread_available == 0) {
sleep(2);
printf("Starting algorithm\n");
pthread_create(&alg, NULL, algorithm, 0);
thread_available = 1;
}
}
}
This sample should create two threads - one will be created at the program beginning and will try to cancel second as soon it starts, second should be rerunned as soon at it was cancelled and say "I'm here". But when algorithm thread cancelled once it doesn't start once again, it says "Starting algorithm" and does nothing, no "I'm here" messages any more. Could you please tell me the way to start cancelled(immediately stopped) thread once again?
UPD: So, thanks to your help I understood what is the problem. When I rerun algorithm thread it throws error 11:"The system lacked the necessary resources to create another thread, or the system-imposed limit on the total number of threads in a process PTHREAD_THREADS_MAX would be exceeded.". Actually I have 5 threads, but only one is cancelled, others stop by pthread_exit. So after algorithm stopped and program went to standby mode I checked status of all threads with pthread_join - all thread show 0(cancelled shows PTHREAD_CANCELED), as far as I can understand this means, that all threads stopped successfully. But one more try to run algorithm throws error 11 again. So I've checked memory usage. In standby mode before algorithm - 10428, during the algorithm, when all threads used - 2026m, in standby mode after algorithm stopped - 2019m. So even if threads stopped they still use memory, pthread_detach didn't help with this. Are there any other ways to clean-up after threads?
Also, sometimes on pthread_cancel my program crashes with "libgcc_s.so.1 must be installed for pthread_cancel to work"
Several points:
First, this is not safe:
int thread_available;
void *stopAlgorithm() {
while (1) {
sleep(6);
if (thread_available == 1) {
pthread_cancel(alg);
printf("Now it's dead!\n");
thread_available = 0;
}
}
}
It's not safe for at least reasons. Firstly, you've not marked thread_available as volatile. This means that the compiler can optimise stopAlgorithm to read the variable once, and never reread it. Secondly, you haven't ensured access to it is atomic, or protected it by a mutex. Either declare it:
volatile sig_atomic_t thread_available;
(or similar), or better, protect it by a mutex.
But for the general case of triggering one thread from another, you are better using a condition variable (and a mutex), using pthread_condwait or pthread_condtimedwait in the listening thread, and pthread_condbroadcast in the triggering thread.
Next, what's the point of the stopAlgorithm thread? All it does is cancel the algorithm thread after an unpredictable amount of time between 0 and 6 seconds? Why not just sent the pthread_cancel from the main thread?
Next, do you care where your algorithm is when it is cancelled? If not, just pthread_cancel it. If so (and anyway, I think it's far nicer), regularly check a flag (either atomic and volatile as above, or protected by a mutex) and pthread_exit if it's set. If your algorithm does big chunks every second or so, then check it then. If it does lots of tiny things, check it (say) every 1,000 operations so taking the mutex doesn't introduce a performance penalty.
Lastly, if you cancel a thread (or if it pthread_exits), the way you start it again is simply to call pthread_create again. It's then a new thread running the same code.

4 Process 4 way synchronization using semaphores (In a C Programming, UNIX environment)

I have a question about synchronizing 4 processes in a UNIX environment. It is very important that no process runs their main functionality without first waiting for the others to "be on the same page", so to speak.
Specifically, they should all not go into their loops without first synchronizing with each other. How do I synchronize 4 processes in a 4 way situation, so that none of them get into their first while loop without first waiting for the others? Note that this is mainly a logic problem, not a coding problem.
To keep things consistent between environments let's just say we have a pseudocode semaphore library with the operations semaphore_create(int systemID), semaphore_open(int semaID), semaphore_wait(int semaID), and semaphore_signal(int semaID).
Here is my attempt and subsequent thoughts:
Process1.c:
int main() {
//Synchronization area (relevant stuff):
int sem1 = semaphore_create(123456); //123456 is an arbitrary ID for the semaphore.
int sem2 = semaphore_create(78901); //78901 is an arbitrary ID for the semaphore.
semaphore_signal(sem1);
semaphore_wait(sem2);
while(true) {
//...do main functionality of process, etc (not really relevant)...
}
}
Process2.c:
int main() {
//Synchronization area (relevant stuff):
int sem1 = semaphore_open(123456);
int sem2 = semaphore_open(78901);
semaphore_signal(sem1);
semaphore_wait(sem2);
while(true) {
//...do main functionality of process etc...
}
}
Process3.c:
int main() {
//Synchronization area (relevant stuff):
int sem1 = semaphore_open(123456);
int sem2 = semaphore_open(78901);
semaphore_signal(sem1);
semaphore_wait(sem2);
while(true) {
//...do main functionality of process etc...
}
}
Process4.c:
int main() {
//Synchronization area (relevant stuff):
int sem1 = semaphore_open(123456);
int sem2 = semaphore_open(78901);
semaphore_signal(sem2);
semaphore_signal(sem2);
semaphore_signal(sem2);
semaphore_wait(sem1);
semaphore_wait(sem1);
semaphore_wait(sem1);
while(true) {
//...do main functionality of process etc...
}
}
We run Process1 first, and it creates all of the semaphores into system memory used in the other processes (the other processes simply call semaphore_open to gain access to those semaphores). Then, all 4 processes have a signal operation, and then a wait. The signal operation causes process1, process2, and process3 to increment the value of sem1 by 1, so it's resultant maximum value is 3 (depending on what order the operating system decides to run these processes in). Process1, 2, and 3, are all waiting then on sem2, and process4 is waiting on sem1 as well. Process 4 then signals sem2 3 times to bring its value back up to 0, and waits on sem1 3 times. Since sem1 was a maximum of 3 from the signalling in the other processes (depending on what order they ran in, again), then it will bring its value back up to 0, and continue running. Thus, all processes will be synchronized.
So yea, not super confident on my answer. I feel that it depends heavily on what order the processes ran in, which is the whole point of synchronization -- that it shouldn't matter what order they run in, they all synchronize correctly. Also, I am doing a lot of work in Process4. Maybe it would be better to solve this using more than 2 semaphores? Wouldn't this also allow for more flexibility within the loops in each process, if I want to do further synchronization?
My question: Please explain why the above logic will or will not work, and/or a solution on how to solve this problem of 4 way synchronization. I'd imagine this is a very common thing to have to think about depending on the industry (eg. banking and synching up bank accounts). I know it is not very difficult, but I have never worked with semaphores before, so I'm kind of confused on how they work.
The precise semantics of your model semaphore library are not clear enough to answer your question definitively. However, if the difference between semaphore_create() and semaphore_open() is that the latter requires the specified semaphore to already exist, whereas the former requires it to not exist, then yes, the whole thing will fall down if process1 does not manage to create the needed semaphores before any of the other processes attempt to open them. (Probably it falls down in different ways if other semantics hold.)
That sort of issue can be avoided in a threading scenario because with threads there is necessarily an initial single-threaded segment wherein the synchronization structures can be initialized. There is also shared memory by which the various threads can communicate with one another. The answer #Dark referred to depends on those characteristics.
The essential problem with a barrier for multiple independent processes -- or for threads that cannot communicate via shared memory and that are not initially synchronized -- is that you cannot know which process needs to erect the barrier. It follows that each one needs to be prepared to do so. That can work in your model library if semaphore_create() can indicate to the caller which result was achieved, one of
semaphore successfully created
semaphore already exists
(or error)
In that case, all participating processes (whose number you must know) can execute the same procedure, maybe something like this:
void process_barrier(int process_count) {
sem_t *sem1, *sem2, *sem3;
int result = semaphore_create(123456, &sem1);
int counter;
switch (result) {
case SEM_SUCCESS:
/* I am the controlling process */
/* Finish setting up the barrier */
semaphore_create(78901, &sem2);
semaphore_create(23432, &sem3);
/* let (n - 1) other processes enter the barrier... */
for (counter = 1; counter < process_count; counter += 1) {
semaphore_signal(sem1);
}
/* ... and wait for those (n - 1) processes to do so */
for (counter = 1; counter < process_count; counter += 1) {
semaphore_wait(sem2);
}
/* let all the (n - 1) waiting processes loose */
for (counter = 1; counter < process_count; counter += 1) {
semaphore_signal(sem3);
}
/* and I get to continue, too */
break;
case SEM_EXISTS_ERROR:
/* I am NOT the controlling process */
semaphore_open(123456, &sem1);
/* wait, if necessary, for the barrier to be initialized */
semaphore_wait(sem1);
semaphore_open(78901, &sem2);
semaphore_open(23432, &sem3);
/* signal the controlling process that I have reached the barrier */
semaphore_signal(sem2);
/* wait for the controlling process to allow me to continue */
semaphore_wait(sem3);
break;
}
}
Obviously, I have taken some minor liberties with your library interface, and I have omitted error checks except where they bear directly on the barrier's operation.
The three semaphores involved in that example serve distinct, well-defined purposes. sem1 guards the initialization of the synchronization constructs and allows the processes to choose which among them takes responsibility for controlling the barrier. sem2 serves to count how many processes have reached the barrier. sem3 blocks the non-controlling processes that have reached the barrier until the controlling process releases them all.

Resources