Problem: I have to increment x1 and x2 variable which should be done by separate threads and next increment of both variables should not be called until previous increment of both variable is not completed.
Problem:
x1 = 0; x2 = 0;
x1++; and x2++; should run parallel on different threads and wait for printing.
should print: x1 = 1 and x2 = 1
x1++; and x2++; should run parallel on different threads and wait for printing.
should print: x1 = 2 and x2 = 2
x1++; and x2++; should run parallel on different threads and wait for printing.
should print: x1 = 3 and x2 = 3
x1++; and x2++; should run parallel on different threads and wait for printing.
should print: x1 = 4 and x2 = 4
…
…
…
x1++; and x2++; should run parallel on different threads and wait for printing.
should print: x1 = 10 and x2 = 10
close the threads
Proposed Solution Using pthread condition: Initialize 4 mutexes and 4 condition variables, and use 2 mutextes to lock main function and rest each for each thread. Both of the threads will wait for the main function to pass the condtion signal to invoke them and after calculation, they are passing back the signal to main thread to move further. sleep of 1 sec is provided asking the threads to invoke properly and get ready to recieve and return signal after calculation.
Pthread Condition Code:
#include <stdio.h>
#include <pthread.h>
pthread_t pth1,pth2;
//Values to calculate
int x1 = 0, x2 = 0;
pthread_mutex_t m1, m2, m3, m4 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c1, c2, c3, c4 = PTHREAD_COND_INITIALIZER;
void *threadfunc1(void *parm)
{
pthread_mutex_lock(&m1);
for (;;) {
pthread_cond_wait(&c1, &m1);
x1++;
pthread_mutex_lock(&m3);
pthread_cond_signal(&c3);
pthread_mutex_unlock(&m3);
}
pthread_mutex_unlock(&m1);
return NULL ;
}
void *threadfunc2(void *parm)
{
pthread_mutex_lock(&m2);
for (;;) {
pthread_cond_wait(&c2, &m2);
x2++;
pthread_mutex_lock(&m4);
pthread_cond_signal(&c4);
pthread_mutex_unlock(&m4);
}
pthread_mutex_unlock(&m2);
return NULL ;
}
int main () {
pthread_create(&pth1, NULL, threadfunc1, "foo");
pthread_create(&pth2, NULL, threadfunc2, "foo");
sleep(1);
int loop = 0;
pthread_mutex_lock(&m3);
pthread_mutex_lock(&m4);
while (loop < 10) {
// iterated as a step
loop++;
printf("Initial : x1 = %d, x2 = %d\n", x1, x2);
pthread_mutex_lock(&m1);
pthread_cond_signal(&c1);
pthread_mutex_unlock(&m1);
pthread_mutex_lock(&m2);
pthread_cond_signal(&c2);
pthread_mutex_unlock(&m2);
pthread_cond_wait(&c3, &m3);
pthread_cond_wait(&c4, &m4);
printf("Final : x1 = %d, x2 = %d\n", x1, x2);
}
printf("Result : x1 = %d, x2 = %d\n", x1, x2);
pthread_mutex_unlock(&m3);
pthread_mutex_unlock(&m4);
pthread_cancel(pth1);
pthread_cancel(pth2);
return 1;
}
Proposed Solution Using Semaphore: Initialize 4 semaphore and invoke separate threads for separate increment of variable. 2 semaphores for passing message to threads for start incrementing and 2 semaphores for passing message to main thread that incrementation is completed. Main thread will wait for semaphore posting from both child threads showing incrementation of both variable is done, then main thread will pass message to both child threads allowing further incrementing.
Semaphore Code:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
//Threads
pthread_t pth1,pth2;
//Values to calculate
int x1 = 0, x2 = 0;
sem_t c1,c2,c3,c4;
void *threadfunc1(void *parm)
{
for (;;) {
x1++;
sem_post(&c1);
sem_wait(&c3);
}
return NULL ;
}
void *threadfunc2(void *parm)
{
for (;;) {
x2++;
sem_post(&c2);
sem_wait(&c4);
}
return NULL ;
}
int main () {
sem_init(&c1, 0, 0);
sem_init(&c2, 0, 0);
sem_init(&c3, 0, 0);
sem_init(&c4, 0, 0);
pthread_create(&pth1, NULL, threadfunc1, "foo");
pthread_create(&pth2, NULL, threadfunc2, "foo");
sem_wait(&c1);
sem_wait(&c2);
sem_post(&c3);
sem_post(&c4);
int loop = 0;
while (loop < 8) {
// iterated as a step
loop++;
printf("Initial : x1 = %d, x2 = %d\n", x1, x2);
sem_wait(&c1);
sem_wait(&c2);
printf("Final : x1 = %d, x2 = %d\n", x1, x2);
sem_post(&c3);
sem_post(&c4);
}
sem_wait(&c1);
sem_wait(&c2);
sem_destroy(&c1);
sem_destroy(&c2);
sem_destroy(&c3);
sem_destroy(&c4);
printf("Result : x1 = %d, x2 = %d\n", x1, x2);
pthread_cancel(pth1);
pthread_cancel(pth2);
return 1;
}
Please suggest me, which one is better way to implement or where can i improve? Any kind of suggestions will be helpful. Thanks in advance. And sorry, if i am repeating myself, because, this problem has become a nightmare for me.. Please help.