Applying C - Condition Variables
Written by Harry Fairhead   
Monday, 12 November 2018
Article Index
Applying C - Condition Variables
First Thread

In the main program we need to declare the mutex, condition variable and the global variable:

pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t myConVar = PTHREAD_COND_INITIALIZER;
int threadid=0;

The main program starts the two threads going and then waits:

int main(int argc, char** argv) {
    srand(time(0));
    pthread_t pthreadA;
    pthread_create(&pthreadA, NULL, threadA, NULL);
    pthread_t pthreadB;
    pthread_create(&pthreadB, NULL, threadB, NULL);
    pthread_mutex_lock(&my_mutex);
    while (threadid == 0) 
pthread_cond_wait(&myConVar, &my_mutex); printf("%d", threadid); pthread_mutex_unlock(&my_mutex); return (EXIT_SUCCESS); }

Notice that the call to pthread_cond_wait is in the form of a while loop. The reason is that the wait can end without any thread signaling. To make sure that it isn’t a spurious wake-up we have to check that threadid has been set to something other than zero. If it is still zero then the wait is restarted. Finally we print the value of threadid and unlock the mutex. Notice you can’t unlock the mutex until the value of threadid has been printed as one of the other threads might update it.

The complete program is:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t myConVar = PTHREAD_COND_INITIALIZER;
int threadid = 0;
void * threadA(void *p) {
    sleep(rand() % 5);
    pthread_mutex_lock(&my_mutex);
    threadid = 1;
    pthread_cond_signal(&myConVar);
    pthread_mutex_unlock(&my_mutex);
}
void * threadB(void *p) {
    sleep(rand() % 5);
    pthread_mutex_lock(&my_mutex);
    threadid = 2;
    pthread_cond_signal(&myConVar);
    pthread_mutex_unlock(&my_mutex);
}
int main(int argc, char** argv) {
    srand(time(0));
    pthread_t pthreadA;
    pthread_create(&pthreadA, NULL, threadA, NULL);
    pthread_t pthreadB;
    pthread_create(&pthreadB, NULL, threadB, NULL);
    pthread_mutex_lock(&my_mutex);
    while (threadid == 0)
pthread_cond_wait(&myConVar, &my_mutex); printf("%d", threadid); pthread_mutex_unlock(&my_mutex); return (EXIT_SUCCESS); }

Now that you have seen how this works you should be able to modify the program so that the main program only resumes when all of the threads have completed.

All you have to do is change the update of the global variable and the signal to:

threadid++;
if(threadid==2) pthread_cond_signal(&myConVar);

With this change each thread increments the global variable but only wakes the main thread up when it reaches 2 and both threads have terminated.

You might want to use this in place of joins if you want to create detached threads.

Now available as a paperback or ebook from Amazon.

Applying C For The IoT With Linux

  1. C,IoT, POSIX & LINUX
  2. Kernel Mode, User Mode & Syscall
  3. Execution, Permissions & Systemd
    Extract Running Programs With Systemd
  4. Signals & Exceptions
    Extract  Signals
  5. Integer Arithmetic
    Extract: Basic Arithmetic As Bit Operations
    Extract: BCD Arithmetic  ***NEW
  6. Fixed Point
    Extract: Simple Fixed Point Arithmetic
  7. Floating Point 
  8. File Descriptors
    Extract: Simple File Descriptors 
    Extract: Pipes 
  9. The Pseudo-File System
    Extract: The Pseudo File System
    Extract: Memory Mapped Files 
  10. Graphics
    Extract: framebuffer
  11. Sockets
    Extract: Sockets The Client
    Extract: Socket Server
  12. Threading
    Extract:  Pthreads
    Extract:  Condition Variables
    Extract:  Deadline Scheduling
  13. Cores Atomics & Memory Management
    Extract: Applying C - Cores 
  14. Interupts & Polling
    Extract: Interrupts & Polling 
  15. Assembler
    Extract: Assembler

Also see the companion book: Fundamental C

<ASIN:1871962609>

<ASIN:1871962617>

Related Articles

Remote C/C++ Development With NetBeans

Raspberry Pi And The IoT In C

Getting Started With C/C++ On The Micro:bit

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner


Extend NGINX With The New JavaScript Module
28/10/2024

Inject middleware functionality into NGINX with the expressive power of Javascript. NGINX JavaScript or NJS for short is a dynamic module under which you can use scripting for hooking into the NGINX e [ ... ]



Improved Code Completion With JetBrains Mellum
29/10/2024

JetBrains has launched Mellum, a proprietary large language model specifically built for coding. Currently available only with JetBrains AI Assistant, Mellum is claimed to provide faster, sm [ ... ]


More News

espbook

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Sunday, 09 June 2019 )