Easy Tutorial: Computer Programming for DUMMIES -- concurrency and pthreads

in #programming8 years ago (edited)


Image source

This tutorial will be about concurrency. Concurrency is a very important aspect of programming. I will be going over pthreads. The pthread library is available for C and C++. If you want to check out the other tutorials in this series, here they are:

Part 1: Hello World!

Part 2: Variables

Part 3: Functions

Part 4: if(), else, else if()

Part 5: Loops

Part 6: Arrays

Part 7: Basic Input/Output

Part 9: Sorting Arrays

Part 10: Random Numbers

Part 11: Colored Text in your Terminal

Part 12: Recursion

Part 13: Binary Search

Part 14: 2D Arrays

Part 15: String Processing

Part 16: Binary, Bitwise Operators, and 2^n

Part 17: Pointers

Part 18: Pointer Arithmetic

Part 19: Object Oriented Programming 1 -- Data Structures

Part 20: Object Oriented Programming 2 -- Classes

Part 21: Object Oriented Programming 3 -- Polymorphism

Part 22: Command Line Arguments

Part 23: Header Files

Part 24: Programming in separate files

Part 25: File I/O

What is concurrency?

Concurrency us when two or more things happen at the same time, or concurrently. As you may know, a computer can only do one thing at a time. A computer is able to multi-task through processes. For simplicity, let's just call these processes tasks. Computers have schedulers that decide what tasks to run and when they run. More important tasks will be at the top of the list, and less important tasks will be at the bottom of the list. So really, there is no true concurrency with computers. They can only go back and forth between tasks. My tutorial will explain one way to create a program that executes several tasks at the same time.

pthreads

The pthread library is one of the most commonly used libraries when threading in C and C++. A thread is just like a process; they run independently from the program that they originate in. Each thread has its own thread ID. This helps keep track of each thread.

Using pthreads

When using pthreads, remember to include the pthread.h file. To create pthreads, first we need to declare a pthread array. This can be easily done:

pthread_t threads[5];
  • this creates an array of 5 threads called threads

After this, we can make our threads with the function pthread_create(). Here are the parameters:

pthread_create(&thread, attributes, thread_function, argument)
  • &thread --> a dereferenced thread
  • attributes --> use NULL for now -- this uses the default attributes
  • thread_function --> a function the thread will execute
  • argument --> an argument for the function -- type void pointer
    • an error will come up if an argument is not present

Here is a common way that this function is used:

int rc;
for(int x = 0; x < 5; x++)
{
    rc = pthread_create(&threads[x], NULL, thread_function, (void *)x);
    if(rc)
        // print error message and exit (optional)
}
  • this creates 5 threads
  • rc --> variable used to test if the pthread_create() call failed
  • call pthread_create()
    • arguments
      • threads --> an array of threads
      • NULL --> default attributes
      • thread_function --> the function that the thread will execute
      • (void *)x --> x cast as a void pointer -- this can be used as the ID
    • store the return value of pthread_create() in rc
  • test to see if the call to pthread_create() failed
    • print an error message if so

To close all of the threads when you are done:

pthread_exit(NULL);

Here is a program I wrote to implement pthreads:

#include<iostream>
#include <pthread.h>
using namespace std;

void* thread_function(void* num)
{   
    long tid = (long)num;
    printf("Thread %d\n", tid);
    fflush(stdout);
}

int main()
{
    pthread_t my_threads[50];
    int success;
    
    for(int x = 0; x < 50; x++)
    {
        success = pthread_create(&my_threads[x], NULL, thread_function, (void *)x);
        if(success)
            cout << "Unable to create thread " << success << endl;
    }
        
    pthread_exit(NULL);
    return 0;
}
  • thread_function() --> the function I will pass to the threads
    • num --> the void pointer handed as an argument
    • tid --> the thread's ID
    • prints "Thread " followed by its ID
    • flushes stdout so that there is no weird output because of the concurrency
  • main()
    • my_threads --> an array of 50 pthreads
    • success --> a variable that will hold the return value of pthread_create()
      • we can use this to print an error message if it happens
    • create 50 threads and call thread_function() for each
      • cast x as a void pointer and pass it to thread_function()
    • if pthread_create() returns an error, print an error message
    • close the threads

Here is the output:

[cmw4026@omega test]$ g++ threads.cpp -lpthread
[cmw4026@omega test]$ ./a.out
Thread 0
Thread 1
Thread 2
Thread 3
Thread 4
Thread 5
Thread 6
Thread 7
Thread 8
Thread 9
Thread 10
Thread 11
Thread 12
Thread 13
Thread 14
Thread 15
Thread 16
Thread 17
Thread 18
Thread 19
Thread 20
Thread 21
Thread 22
Thread 23
Thread 24
Thread 25
Thread 26
Thread 27
Thread 28
Thread 29
Thread 30
Thread 31
Thread 32
Thread 33
Thread 34
Thread 35
Thread 36
Thread 43
Thread 42
Thread 37
Thread 38
Thread 39
Thread 40
Thread 41
Thread 49
Thread 48
Thread 47
Thread 44
Thread 45
Thread 46
[cmw4026@omega test]$
  • If you want evidence that these threads are running concurrently, after "Thread 36," they begin to appear out of order. This is because the threads with the larger thread IDs finish before some of the threads with the smaller thread IDs
  • When compiling, the "-lpthread" flag must be included

I hoped this helped! Leave any suggestions in the comments.


Sort:  

Hopefully the people that want to make Steemit into a learning platform remember where all this is. You've pulled this off where others have failed. I'll keep voting :)

Thanks a lot! I appreciate it.

I understand a lot from your way of thinking, is there any posibillity to find something like this in c#?

Coin Marketplace

STEEM 0.18
TRX 0.13
JST 0.028
BTC 57497.94
ETH 3099.12
USDT 1.00
SBD 2.32