Introduction To THREADS
Threads, like processes are a mechanism to allow a program to do more than one thing at a time. In Linux when a process is created, it already contains a thread, used to execute the main() function. Threads are implemented as lightweight process. A process can have multiple threads of execution and they all share the same process address space and system state information. When a thread is created in a process, the new thread of execution gets its own stack but shares global variables, file descriptors, signal states. When a program creates another thread, nothing is copied. The creating and the created thread share the same memory space, file descriptors, and other system resources as the original. If one thread changes the value of a variable, for instance, the other thread will see the modified value. Similarly, if one thread closes a file descriptor, other threads may not read from or write to that file descriptor. Because a process and all its threads can be executing only one program at a time, if any thread inside a process calls one of the exec functions, all the other threads are ended.
Linux implements the POSIX thread api. All thread functions and data types are declared in the header file <pthread.h>. to use these library calls link the program with the threads library using -lpthread, as they are not included in standard C library.
Thread Creation:
Each process is identified by a thread id of type pthread_t. Upon creation each thread executes a thread function. When this function returns, thread ends. Function to create a thread is
pthread_create(pthread_t* thread, pthread_attr_t * attr, void *(*routine), (void *), void *arg);
thread is a pointer to a pthread_t structure that will be initialized by the function. Later, this structure can be used to reference the thread.
Attr is a pointer to an optional structure pthread_attr_t. This structure can be manipulated using pthread_attr_*() functions. It can be used to set various attributes of the threads (detach policy, scheduling policy, etc.)
start_routine is the function that will be executed by the thread
arg is the private data passed as argument to the start_routine function
Thread Exit :
A thread can exit by calling pthread_exit .This function may be called from within the thread function or from some other function called directly or indirectly by the thread function. The argument to pthread_exit is the thread’s return value. Syntax of pthread_exit is
void pthread_exit(void *retval).
Thread Joining :
When the main() function exits, all threads of the application are destroyed. The pthread_join() function call can be used to suspend the execution of a thread until another thread terminates. This function must be called in order to release the resources used by the thread, otherwise it remains as zombie. Syntax of pthread_join is
int pthread_join(pthread_t thread, void **thread_return);
where thread the thread for which to wait, that was filled by the pthread_create function call. Second argument point to the return value of the thread.
Advantages of using threads:
-
Improves program performance.
-
Reduce system overheads.
-
Enables the better utilization of hardware in multi-core cpu’s.
-
Less demanding on resources as compared to multiple processes.
Disadvantages :
-
Program complexity and requires very careful design.
-
Debugging a multi-threaded application is a difficult task.
-
Deadlocks.