Applying C - Pthreads
Written by Harry Fairhead   
Monday, 25 September 2023
Article Index
Applying C - Pthreads
Pthreads
Joinable And Detached Threads
Thread Local

You can create a thread local in Pthreads using:

__thread

as a qualifier on any static or global variable. This is a widely supported POSIX standard but there are other ways of doing the job and in particular C11 introduced its own way that works if you are using C11 threading.

As an example, let’s try two simple counting threads sharing a global counter variable:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int counter;
void * count(void *p) {
    for (int i = 0; i < 5000; i++) {
        counter++;
    }
    return &counter;
}
int main(int argc, char** argv) {
    pthread_t pthread1;
    int id1 = pthread_create(
&pthread1, NULL, &count, NULL); pthread_t pthread2; int id2 = pthread_create(
&pthread2, NULL, &count, NULL); void *returnval1; void *returnval2; pthread_join(pthread1, &returnval1); pthread_join(pthread2, &returnval2); printf("%d\n", *(int*) returnval1); printf("%d\n", *(int*) returnval2); return (EXIT_SUCCESS); }

You can see that the counter variable is global and both threads increment it 5000 times. It might appear that the result of printing the two return values would be 5000 each time. However, as both threads access the variable in an uncontrolled way sometimes things go wrong as both threads access the count variable at the same time - take the same value it contains, increment it and store the same incremented value back. What should have been an increment by two becomes an increment by one. If you run the program you will get results in the 6000 region indicating the simultaneous updates aren't that rare.

Now if you change the declaration of count to:

__thread int counter;

and rerun the program you will see that returnval1 prints 5000 and returnva2 prints 5000 also. Each thread has its own copy of the global count variable and there is no sharing and hence no interaction. Of course the variable is still global and any other function executed on the same thread will have access to its value.

A thread local variable is safe to use within a thread but how do we correct the counter program with a shared global so that we always get the right answer - the most obvious answer is use a lock but there is another.

Included in chapter but not in this extract:

  • Atomic Operations and Locks
  • Mutex
  • Condition Variables
  • First Thread to Finish
  • Scheduling
  • Deadline Scheduling

Summary

  • Multi-tasking is becoming increasingly common, even on small machines.

  • The original way of creating new processes is to use a fork which creates a new copy of the currently running process. Today it is more common to use threads, which are more efficient and closer bound than a fork.

  • Although C11 has a standard for threading, the original Pthreads library is still the most common way of implement threading.

  • Pthreads supports joinable and detached threads. A joinable thread can return a result to a thread that waits on its completion, whereas a detached thread cannot do this.

  • To avoid simultaneous access to resources you need to use locking. The mutex is one of the most basic locking devices.

  • A more complex locking device is the condition variable, which can be used to synchronize threads that can wait on the condition variable.

  • Threads and processes need to be scheduled by the operating system. Linux has a real time scheduling policy called FIFO, which is worth using, but the slightly less commonly used earliest deadline scheduling (EDS) is better.

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


Remembering Thomas Kurtz, Co-creator of BASIC
15/11/2024

Thomas Eugene Kurtz, the co-founder of the BASIC programming language, has died at the age of 96. BASIC, which was developed for the purpose of education, popularized computer programming making it ac [ ... ]



JetBrains Improves Kubernetes Support In IDE Upgrades
12/11/2024

JetBrains has improved its IDEs with features to suggest the logical structure of code, to streamline the debugging experience for Kubernetes applications, and provide comprehensive cluster-wide Kuber [ ... ]


More News

espbook

 

Comments




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



Last Updated ( Tuesday, 26 September 2023 )