Monday, October 25, 2010

Concurrent Programming - Basics

        Till now we have been using sequential programming which executes a single stream of instructions and operations. Concurrent programming is very much complex than sequential programming. Here several streams of operations executes concurrently. Each sequence of instructions are called threads.
    
        To create thread in C we are including a header file called pthread.h and we can create the thread using
      int pthread_create(pthread_t *thread, pthread_attr_t *attr, void* (*start_routine)(void*), void* arg); 

        We are not required to know the nature of the type pthread_t and pthread_attr_t. So we can say it as type pthread. Third argument is an address of a function which can return anything and accept anything. Fourth argument is the value to the function whose address is in the third argument. Thus we can create different threads of same function which vary in their return type and accept type.

         We have to create the thread inside the main(). As long as the main thread lives, the child thread also lives. So we have to provide a infinite loop at the end of the main().

         When compiling a program we have to link our program to pthread. So compile the program with -lpthread  option.  

Synchronization using mutex

        Mutex is a Mutual Exclusion device. Mutual Exclusion means if there are two events A and B, these two events must not happen at the same time. Mutex has two different states. Locked-->owned by one thread, Unlocked-->not owned by any threads. We can define the mutex variable as a type pthread_mutex.
        For locking: pthread_mutex_lock(&mutex);
        For unlocking: pthread_mutex_unlock(&mutex);
       For initializing:pthread_mutex_init(&mutex, 0);
where mutex is a type pthread_mutex.

Semaphore synchronization
        A more general synchronization mechanism is semaphore. Here we have to include a header file called semaphore.h. sem_wait and sem_post are the two operations similar to mutex lock and unlock. A semaphore should be declared as a type sem_t. On initializing sem_init(sem_t *sem, int pshared, unsigned int value); the first argument is a address of sem object, second is always zero and the third argument is the initial value of the semaphore.

sem_post(&value); -->It increments the value of the semaphore variable.
sem_wait(&value); -->It decrements the value of the semaphore variable. If it is zero them waits for a sem_post() operation to occur.

pthread_join and pthread_exit

        pthread_exit(0) -->A thread uses this to terminate  itself.
      pthread_join(pthread_t t, void** thread_return) --> It makes the main thread to wait until this thread t exits.    

Condition Variables

        Condition variables enables threads to wait until a particular condition occurs. Condition variables are of type pthread_cond_t and has two fundamental functions. They are pthread_cond_wait which has two arguments- address of the condition variable and address of the locked mutex and pthread_cond_broadcast which one argument- the condition variable. pthread_cond_wait release the lock and sleeps the thread until it receives a broadcast message. When it receives a broadcast message, thread reacquires the lock and wakes up.

No comments:

Post a Comment