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 11: Colored Text in your Terminal
Part 16: Binary, Bitwise Operators, and 2^n
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 24: Programming in separate files
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
- arguments
- 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.
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 :)
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Thanks a lot! I appreciate it.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
I understand a lot from your way of thinking, is there any posibillity to find something like this in c#?
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Of course!
https://www.tutorialspoint.com/csharp/csharp_multithreading.htm
And thanks! I try to keep it super simple.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit