>

Monday, 14 December 2015

pthreads

What are pthreads?
Hardware vendors each have their own implementations of threads. In 1995, in order to make programs portable, the POSIX (Portable Operating System Interface for UNIX) standard was established.
? The first standard was IEEE POSIX 1003.1, 1995 Edition.
? The POSIX standard has evolved; the latest version is IEEE Standard 1003.1, 2004 Edition.
? POSIX threads are called POSIX threads, or pthreads for short.
Note that when using pthread library, you must link with the -lpthread flag, For example: g++ myProgram.C -lpthread
Advantages of threading:
1. Shared memory offers speed gains
Because there is not intermediate copy or process-to-process communication, there are significant speed gains that come from multithreading. Multithreading offers significantly more bandwidth than other methods such as using MPI.
2. forking versus multithreading

Lawrence Livermore National Laboratories tested using fork versus creating pthreads on a variety of platforms. They called each 50,000 times; the times are listed below. It is approximately 10X faster to create, join, and delete threads than it is to use fork.

How are threads created/destroyed?
Thread creation
Initially, main() starts with only one thread. If additional threads are needed, you must create them. Threads have the following characteristics:
? Threads may create new threads.
? All threads are peers.
? There is no implied hierarchy among threads.
Remember, when using the pthread library, you must link with the -lpthread flag, for example, g++ myProgram.C –lpthread
Creating a thread - Syntax
When creating a thread, the following syntax must be used.



1. pthread creation API corresponds to pthread_create in the image
2. Unique thread identifier – user defined corresponds to thread in the image
3. Attributes - NULL is the default; this is where you set the thread attributes. To manage thread attributes, you may also use the following APIs: 
a. pthread_attr_init
b. pthread_attr_setxxx
c. pthread_attr_destroy corresponds to attr in the image
4. Name of the routine corresponds to start_routine in the image 
o The operating system decides when the routine is executed.
5. Argument - Single void * arg to C routine corresponds to arg in the image 
o In order to pass multiple arguments, create a struct or class object and pass a pointer to it.

Thread termination
Threads may be terminated in a variety of ways, including the following:
? When start_routine() finishes and returns, the thread automatically dies.
? When the entire process is terminated due to a call to either the exec() or exit() routines, then all threads die.
? When the thread calls pthread_exit() 
o Allows the thread to return a value to the routine that created the thread
? Any thread can cancel another thread by calling pthread_cancel() 
For example: pthread_cancel ( pthread_t *thread );
It is important to remember the following about thread termination:
? Pthread_exit() and pthread_cancel() do not close any files when called. 
o You should explicitly close any files that you open.
? If main() calls pthread_exit() the main routine stops, but all other threads will continue running until the last thread finishes its work and then the process will die.

Example1:

There is a for loop that calls pthread_create() five times passing the following:
Thread = t
Attr = NULL (taking the default)
Start_routine = PrintHello
Arg = (void *)t
It is important to remember the following: 
Threads are created at the OS’s discretion.
Threads are run at the OS’s discretion.
pthread_exit() must be called in order to allow the threads to continue working and finish; just allowing main() to exit would have killed all the threads at that moment and threads 2, 3, and 4 would not have called PrintHello.

How do I pass arguments to threads?
When calling pthread_create there are good and bad ways to pass data to thread functions, for example:
A BAD method of passing arguments would be to pass in the address of some variable which may change (“t” in the example below). Note in the example below that since PrintHello may execute at an arbitrary time (at the discretion of the operating system) this routine is going to get an undetermined value of t. The situation above will lead to incorrect/random program behavior.
int rc;
long t;
for(t=0;t<NUM_THREADS;t++) {
printf("Creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &t);
...
}



In order to avoid the previous problem, a recommended method of passing arguments is to create an array of tasks to store the thread work packages, in such a manner as to ensure that each taskid does not change with time.
How are static variables treated across threads?
Threads share all global variables, including:
Function scope static variables
File scope static variables
File scope non-static variables
Class-scope static variables
Modifications to static variables need to be carefully synchronized if multiple threads are executing
Static variables in multithreaded code

0 comments:

Post a Comment