Friday, January 9, 2009

Linux - Threads-1

Threads, like processes are a mechanism to allow a program to do more than one thing at a time.

Linux schedules threads asynchronously, interrupting each thread from time to time to give other a chance to execute.

Threads exists within a process. When we invoke a program, Linux creates a new process and in that process creates a single thread, which runs sequentially. That thread can create additional threads; all these threads run the same program in the same process, but each thread may be executing a different part of the program at any given time.

fork() creates child process with its parent's virtual memory, file descriptors and so on copied. Where as in threads, When a program creates another thread, nothing is copied. The created thread share the same memory space, file descriptors, and other system resources as the original. If a thread changes the value of a variable, the other thread subsequentially will see the modification.

If any thread inside a process calls one of the exec functions, all the other threads are ended.

Linux implements the thread API (knows as pthreads)
All thread functions and data types are declared in file /pthread.h/

The thread functions are not in the standard C library, instead they are in libpthread, so we should add -lpthread to the command line when we link our program.

Each thread is identified by thread ID. Data type is pthread_t

Upon thread creation, each thread executes a thread_function. This is an ordinary function and contains the code that thread should run. When the function returns, the thread exits.

pthread_create() function creates a new thread.

A call to pthread_create() returns immediately, and the original thread continues executing the instructions following the call.

If successful, the pthread_create() function returns zero. Otherwise, an error number is returned to indicate the error.

ex:
pthread_create(&pid, NULL, &print_x, NULL);
/* pid - thread id of type pthread_t
NULL (2nd parameter) - specifies the thread attributes. NULL is for default attributes
&print_x - 3rd parameter is the pointer to the function that the thread should run
NULL - 4th parameter is the pointer to the parameters that has to be passed to the thread calling funciton. */

Generally, all the parameters required by the function that the thread should call are placed in a structure and the pointer to the structure is passed when the thread is created.

Ex:
#include/pthread.h/
#include/stdio.h/


struct char_print_params // structure for passing params to thread func
{
char c;
int count;
};


void* char_print(void *params) // thread func
{
struct char_print_params *p = (struct char_print_params*)params;
int i;
for(i=0;icount;i++)
fputc(p->c, stdout);
return NULL;

}
int main() {
pthread_t pid1,pid2;
struct char_print_params c1,c2;

c1.c = 'x';
c1.count = 200;

c2.c = 'o';
c2.count = 300;


pthread_create(&pid1, NULL, &char_print, &c1); // create thread 1 to print 'x'
pthread_create(&pid2, NULL, &char_print, &c2); // create thread 2 to print 'o'

return 0;
}


Joining the threads:

Force the main() to wait for the thread to finish.
pthread_join() will be used to wait for the thread. it takes 2 params, one is the thread id, 2nd is the pointer to take the return value of thread. NULL is passed if we don't need the return value.

Ex:
pthread_join(pid1,NULL);

A thread cannot call pthread_join() to join itself.


** Make sure that any data you passed to the thread by reference is not deallocated, even by a different thread, until you are sure that the thread is done with it. This is true for both local variables and global variables.


pthread_self() - return the thread ID of the thread in which this function is called.

pthread_equal() - compares the thread ids.

pthread_cancel() - We can cancel the thread using this function. Later, we should join the cancelled thread to free up the resources. An asynchronously cancellable thread can be cancelled at any point in its execution. Where as a synchronously cancellable thread may be cancelled only at particular places in its execution. These places are called as cancelling points.

pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) - This disables the cancellation of the thread.

Critical Sections:
A critical section is a sequence of code that must be executed in its entirity or not at all; in other words, if a thread begins executing the critical section, it must continue until the end of the critical section without being cancelled.



No comments: