Note that there are some explanatory texts on larger screens.

plurals
  1. POSemaphore Vs Condition Variables in multithreading?
    primarykey
    data
    text
    <p><strong>Problem</strong>: 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.</p> <p>Problem:</p> <pre><code>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 </code></pre> <p><strong>Proposed Solution Using pthread condition</strong>: 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.</p> <p><strong>Pthread Condition Code:</strong></p> <pre><code> #include &lt;stdio.h&gt; #include &lt;pthread.h&gt; 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(&amp;m1); for (;;) { pthread_cond_wait(&amp;c1, &amp;m1); x1++; pthread_mutex_lock(&amp;m3); pthread_cond_signal(&amp;c3); pthread_mutex_unlock(&amp;m3); } pthread_mutex_unlock(&amp;m1); return NULL ; } void *threadfunc2(void *parm) { pthread_mutex_lock(&amp;m2); for (;;) { pthread_cond_wait(&amp;c2, &amp;m2); x2++; pthread_mutex_lock(&amp;m4); pthread_cond_signal(&amp;c4); pthread_mutex_unlock(&amp;m4); } pthread_mutex_unlock(&amp;m2); return NULL ; } int main () { pthread_create(&amp;pth1, NULL, threadfunc1, "foo"); pthread_create(&amp;pth2, NULL, threadfunc2, "foo"); sleep(1); int loop = 0; pthread_mutex_lock(&amp;m3); pthread_mutex_lock(&amp;m4); while (loop &lt; 10) { // iterated as a step loop++; printf("Initial : x1 = %d, x2 = %d\n", x1, x2); pthread_mutex_lock(&amp;m1); pthread_cond_signal(&amp;c1); pthread_mutex_unlock(&amp;m1); pthread_mutex_lock(&amp;m2); pthread_cond_signal(&amp;c2); pthread_mutex_unlock(&amp;m2); pthread_cond_wait(&amp;c3, &amp;m3); pthread_cond_wait(&amp;c4, &amp;m4); printf("Final : x1 = %d, x2 = %d\n", x1, x2); } printf("Result : x1 = %d, x2 = %d\n", x1, x2); pthread_mutex_unlock(&amp;m3); pthread_mutex_unlock(&amp;m4); pthread_cancel(pth1); pthread_cancel(pth2); return 1; } </code></pre> <p><strong>Proposed Solution Using Semaphore:</strong> 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.</p> <p><strong>Semaphore Code:</strong></p> <pre><code> #include &lt;stdio.h&gt; #include &lt;pthread.h&gt; #include &lt;semaphore.h&gt; //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(&amp;c1); sem_wait(&amp;c3); } return NULL ; } void *threadfunc2(void *parm) { for (;;) { x2++; sem_post(&amp;c2); sem_wait(&amp;c4); } return NULL ; } int main () { sem_init(&amp;c1, 0, 0); sem_init(&amp;c2, 0, 0); sem_init(&amp;c3, 0, 0); sem_init(&amp;c4, 0, 0); pthread_create(&amp;pth1, NULL, threadfunc1, "foo"); pthread_create(&amp;pth2, NULL, threadfunc2, "foo"); sem_wait(&amp;c1); sem_wait(&amp;c2); sem_post(&amp;c3); sem_post(&amp;c4); int loop = 0; while (loop &lt; 8) { // iterated as a step loop++; printf("Initial : x1 = %d, x2 = %d\n", x1, x2); sem_wait(&amp;c1); sem_wait(&amp;c2); printf("Final : x1 = %d, x2 = %d\n", x1, x2); sem_post(&amp;c3); sem_post(&amp;c4); } sem_wait(&amp;c1); sem_wait(&amp;c2); sem_destroy(&amp;c1); sem_destroy(&amp;c2); sem_destroy(&amp;c3); sem_destroy(&amp;c4); printf("Result : x1 = %d, x2 = %d\n", x1, x2); pthread_cancel(pth1); pthread_cancel(pth2); return 1; } </code></pre> <p>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.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload