In this chapter we shall learn about:
1. Pthread Introduction.
2. Header file required for pthreads:
3. Types of threads
4. Kernel Level Threads
5. User Level Threads.
6. POSIX thread Library API:
7. How to Synchronization between threads
8. Example 1: Simple thread creation:
9. Example 2: Passing parameter to a thread
10. Joining and Detaching a thread:
11. Example 3: Simple thread creation with join system call
12. Example 4: Simple thread creation with detach system call
Pthread Introduction:
1. A thread is a light weight process.
2. It has it’s own stack and execution state, but shares the address space with it’s parent.
3. Threads are used to provide synchronization and concurrency.
4. A thread maintains its own:
Header file required for pthreads:
#include <pthread.h>
Types of threads
There are 2 different types of threads
1. Kernel Level Threads
2. User Level Threads.
1. Kernel Level Threads
- Each process contains at least one kernel thread.
- Kernel maintains context information for the process and the threads.
- Kernel scheduling is performed to switch between the threads.
- Kernel routines can be multithreaded
- Kernel threads take much longer than user threads to be swapped
2. User Level Threads.
- User threads are managed and scheduled in userspace
- Thread switching does not involve the kernel
- ULTs can run on any OS
POSIX thread Library API:
1. To create a thread:
int pthread_create( pthread_t *pthread, const pthread_attr_t *attr, void *( *start_routine) (void *), void *arg );
pthread_create will take 4 arguments:
1. pthread: It is the thread ID.
2. attr:
Thread attributes can be:
PTHREAD_CREATE_JOINABLE,
PTHREAD_CREATE_DETACHED
When an attribute is not specified, below are the default values:
It is unbounded
It is non detached
It has a a default stack and stack size
It inherits the parent’s priority
3. Function to be called, we shall see in detail below.
4. additional arguments. We shall see in example 2.
2. To wait for a thread to finish:
int pthread_join( pthread_t thread, void **value_ptr);
3. To detach a thread:
int pthread_detach( pthread_t thread);
4. To compare two thread handles:
int pthread_equal( pthread_t thread1, pthread_t thread2);
5. To cancel a thread:
int pthread_cancel( pthread_t thread);
6. To exit a thread:
pthread_exit(void *retval);
Function prototype for a thread:
Below is the pthread_create API:
int pthread_create( pthread_t *pthread, const pthread_attr_t *attr, void *( *start_routine) (void *), void *arg );
If you look at the start routine, “void *( *start_routine) (void *)”.
It means that the function that the thread is calling should be:
1. The function should accept only 1 input parameter of the type (void *)
2. The return value type of this function is void *
Below is the function should look like:
void * start_routine( void * arg ) { //statements }
How to Synchronization between threads
Below are the different ways to create a synchronization between 2 threads:
1. Mutex variable functions
2. condition variable functions
3. pthread_once function
4. Reader Writer exclusion
Now let’s see how to create a thread:
Below are the API used to create and terminate a thread:
pthread_create (thread,attr,start_routine,arg)
pthread_exit (status)
pthread_cancel (thread)
pthread_attr_init (attr)
pthread_attr_destroy (attr)
Below are the thread attributes
Below are the resources that are shared along with the process.
Process ID, Process Group ID, and Session ID
Controlling Terminal
Credentials
Open File Descriptors
Record Locks
Signal Dispositions (making signals difficult to use)
Current Working Directory, Root Directory, etc…
Timers
Resource Limits
Below are the resources that are unique to a thread.
Thread ID
Signal Mask
errno and Condition Codes
Stack and Stack Pointer
Program Counter
General Purpose Register Values
Example 1: Simple thread creation:
#include <stdio.h> #include <pthread.h> #include <stdlib.h> void * thread1() { printf("Hello from www.ProDeveloperTutorial.com\n"); } int main() { int status; pthread_t tid1; pthread_create(&tid1,NULL,thread1,NULL); return 0; }
Example 2: Passing parameter to a thread
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <pthread.h> //for more tutorials on C, C++, STL, DS, Linux visit www.ProDeveloperTutorial.com void *myFun(void *arg) { int *p; // Pointer to an integer variable int x; p = (int *) arg; // Casting "(void *)" type to "(int *)" x = *p; printf("\n The input parameter is %d", x ); return(NULL); } int main(int argc, char *argv[]) { pthread_t tid; int param; param = 12345; pthread_create(&tid, NULL, myFun, & param); pthread_join(tid, NULL); }
Output:
The input parameter is 12345
Joining and Detaching a thread:
Below is the API used to join a thread:
pthread_join (threadid,status):
pthread_join is used to wait till the child thread to terminate.
Below is the API used to detaching a thread:
pthread_detach (threadid)
pthread_detach is used to delete the thread resource once the execution has been completed.
Example 3: Simple thread creation with join system call
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <pthread.h> //for more tutorials on C, C++, STL, DS, Linux visit www.ProDeveloperTutorial.com void *myFun(void *arg) { printf("\nHello World !\n"); return(NULL); } int main(int argc, char *argv[]) { pthread_t tid; if ( pthread_create(&tid, NULL, myFun, NULL) ) { printf("\nCannot create thread"); exit(1); } printf("\nMain now waits for thread tid to finish....") ; pthread_join(tid, NULL); exit(0); }
Output:
Main now waits for thread tid to finish.... Hello World !
Example 4: Simple thread creation with detach system call
By default when you create a thread without any attributes, it will create a join able threads. It means that, the resources acquired by that thread needs to be destroyed by other threads with pthread_join().
But if you make a thread as detached, then the resources are automatically freed upon termination.
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <pthread.h> //for more tutorials on C, C++, STL, DS, Linux visit www.ProDeveloperTutorial.com void *myFun(void *arg) { pthread_detach(pthread_self()); sleep(1); printf("Thread Fn\n"); pthread_exit(NULL); } int main(int argc, char *argv[]) { pthread_t tid; int ret = pthread_create(&tid, NULL, myFun, NULL); if (ret != 0) { perror("Thread Creation Error\n"); exit(1); } printf("After thread created in Main\n"); pthread_exit(NULL); }
Output:
After thread created in Main Thread Fn