I need a C code for a program which N threads can communicate with eachother.
each thread id can wait for whichever thread id it wants.
each thread id can signal which ever thread id it wants.
they can wait and signal each other multiple times.
when a thread is signaled it means it can stop waiting for the thread and that the two threads are synched, like a barrier but implemented with mutex and condition variables instead.
each thread that waits are waiting to be signaled by a specific thread with an id called buddy and with the right int:synch_point and int:group, if they are not the same then the thread has to continue waiting until such signal has been received.
void signal_and_wait_for_thread(thread_data_t *thread_data, int myid, int buddy, int sync_point, int stride) {
// Lock myid mutex and update the shared data
pthread_mutex_lock(&thread_data->mutexes[myid]);
thread_data->sync_points[myid] = sync_point;
thread_data->strides[myid] = stride;
//thread_data->ready[myid] = 1;
pthread_cond_broadcast(&thread_data->conds[myid]);
pthread_mutex_unlock(&thread_data->mutexes[myid]);
// Lock buddy mutex and wait for the buddy thread to reach the same sync point and stride
pthread_mutex_lock(&thread_data->mutexes[buddy]);
while (
thread_data->sync_points[buddy] != sync_point ||
thread_data->strides[buddy] != stride) {
pthread_cond_wait(&thread_data->conds[buddy], &thread_data->mutexes[buddy]);
}
//thread_data->ready[buddy] = 0;
pthread_mutex_unlock(&thread_data->mutexes[buddy]);
}
The code above tries to implement this signal and wait for multiple thread ID’s. Problem is it is reaching deadlock. What is the proper way to synchronize two threads amongst N threads that might want to communicate with the same thread. without introducing too much overhead with unneccesary mutexes.
7
The code in your question looks fine to implement the scheme you’ve described. Presuming the variables are all initialised correctly, the problem likely comes in how you’re using this function, because it is quite prone to deadlock if the logic of your calling program is flawed.
If, for example, you have thread A call signal_and_wait_for_thread(data, ID_A, ID_B, 1, 10);
and thread B calls signal_and_wait_for_thread(data, ID_B, ID_A, 1, 20);
then it will obviously deadlock: thread A will be waiting for thread B to set stride 10, and thread B will be waiting for thread A to set stride 20, and neither will ever be able to make progress.