This is going to be a starting tutorial on how to use threads. It will only assume basics of c/c++ i.e. you know how to write a function and use variables, what is a basic pointer etc. you would be just fine.
The first thing to know is, there is no threading header / library available with the basic c/c++ compiler. So you need some extended one. That means you cannot create threads like “include <stdio.h>” and use printf(). You need to acquire a library first.
POSIX (Portable operating system interface) is a standard for API on all variants of Unix systems and contains a library called pthread. Unfortunately, it doesn’t run directly (at least) on windows and to use this code on windows you need something like
OpenMP.org
Thread issues have been asked around on the forum such as
http://forum.codecal...ix-threads.html
The below code is written and tested on Fedora Linux and I will try to keep it as basic as possible.
What are threads any way and why do we need them?
Ah… But I guess I should clarify the exact meaning and need for creating and using threads. Everyone would know the name though.
Generally when you write a program, there is a single path / flow of execution. Your code starts from first line of main and keep proceeding line by line towards the end of this function. But what if you have a need like for e.g. to read from screen whenever the user types AND print a message whenever it is received from network. If you simply try to accommodate both of these tasks in a simple main either you have to code reading from screen first or reading from network first. Even if these calls are non-blocking (it means program does not hang as in “cin” until you enter characters on the screen), still main would follow THE ORDER of execution of your statement i.e. reading from screen first and then latter reading from network. So your program will always be dependable on the order and the true meaning of it cannot be achieved in a single threaded main program.
A common solution is to create a new thread other than main. One of these two handles ‘reading from network’ where as the other ‘reads from console’.
A picture speaks for a thousand words. So here it goes.
threads1.jpg 31.5K
278 downloadsBasic code details
The header file to include for threads is called “pthread.h”. This library is usually available on any Linux system. So you don’t have to worry about installing separately.
#include <iostream>
#include <pthread.h>
using namespace std;
void * thread_fun(void * param)
{
cout << "Running thread" << endl;
return param;
}
int main ()
{
pthread_t thread_id;
int param;
cout << "testing basic c++" << endl;
pthread_create(&thread_id, NULL, thread_fun, ¶m);
cout << "Running main after thread creation" << endl;
return 0;
}
First we need to create a separate function which will be the starting point of thread i.e. it will be the code that is executed as a separate thread. We have a “thread_fun” here which takes a void * p as a parameter and return the same. This is required by definition of the API. Why? Because when you create a thread you most likely will need to pass some information to it and return something useful from it whenever you are making any practical application beyond just demo of how thread works. But obviously you could ignore the parameters if they are not needed as I have done in the code. The rationale of using a void pointer is that you should be able to pass anything. Any number of elements can be packed in a structure or an array and passed to thread where it can be interpreted.
In main we create a variable of type pthread_t which as it’s name indicates is a numeric value for a thread’s id. This will be similar to an integer which upon successful creation of a thread will contain the thread’s numeric id. Thread can be referred to using this id and this value serves as the basic point of identification for a thread.
Then is the call pthread_create, first parameter of which the same thread id mentioned already. The second one is a structure called thread_attr which can be used to create thread with specific values or configurations. Most of the times we pass a null which means create a thread with default values. You will see this utilized once you start playing around a little bit more with threads.
The next parameter is a function pointer to the function which is the starting point of thread. We pass “thread_fun” here as mentioned above. Please note that it will be a syntax error if thread fun’s signature (parameters and return values) do not match the one mentioned in code.
The last parameter can basically be the arguments passed to the thread. Currently we haven’t used it and just passed an integer without actually using it anywhere.
The return value of the thread function tells us if it was created successfully or there was any error.
How to Build and Execute
Assuming the source file’s name is thread.cpp, following is the command line
# g++ thread.cpp –o thread –lpthread
# ./thread
g++ is the compiler since I wrote c++ code. Gcc can be used too if written code is ANSI c. –o tells the compiler to name the binary executable file as “thread” which will be created in the current folder.
-lpthread is basically telling the compiler to link the exe with pthread library. Had we been using a header file such as “math.h” it would be –lm (because math.h’s should form is only m). If this linker statement is not added program would give linker error for not being able to locate the header file “pthread.h” and all of it’s definitions.
More functions to be used with Threads
pthread_self();
It returns a pthread_t object which basically is the thread id. So if you need current thread’s id inside the current thread, this function is helpful.
pthread_equal();
Takes two threads as parameters and returns 0 if both of their thread id’s are equal.
pthread_join();
A very very important function. It takes a thread id object and waits for the completion of that thread. For e.g. in the program above, there is no guarantee if main terminates first or the new thread. If you did some work in main AFTER creating the thread, and then once you are done with that work and you want to wait for the thread to complete before you exit main, you would use this function.
pthread_exit();
Can be used by a thread to force itself to terminate. Remember calling exit() would terminate the whole program.
pthread_cancel();
One thread can instruct another thread to terminate under specific circumstances. It takes a thread id object as parameter.
I will add some more code to above function in which we will pass some value to thread, do some operation, return a value from thread, and wait for thread termination in main where we read that value before exit.
#include <iostream>
#include <pthread.h>
using namespace std;
void * thread_fun(void * param)
{
int value = *(int *)param; // Remember param is void pointer, so it needs to be casted into int BEFORE accessing value
// Otherwise, there is no way for void pointer to know how many bytes to read when * is used.
cout << "Param's value received in thread is: " << value << endl;
(*(int *)param)++; // increment param's value by 1
return param;
}
int main ()
{
pthread_t thread_id;
int param = 10;
void * t_status_void_p;
int * thrd_status_ptr;
int status;
cout << "testing basic c++" << endl;
status = pthread_create(&thread_id, NULL, thread_fun, ¶m);
if(status != 0)
return -1;
pthread_join(thread_id, &t_status_void_p); // note the status has to be a double pointer
thrd_status_ptr = (int *)t_status_void_p;
cout << "Running main after thread's completion with value:" << *thrd_status_ptr << endl;
return 0;
}
I plan to extend more details and useful programs on threads if there is enough interest indicated by readers. I also intend to improve my previous TCP based concurrent server
http://forum.codecal...pi-linux-c.html
into truly concurrent server using threads.
Edited by fayyazlodhi, 26 July 2011 - 12:14 AM.
typos


Sign In
Create Account


Back to top









