240 likes | 342 Views
Introduction to Threads. Process Vs Thread. A Process is an executable program with single thread of control. It’s is also called as Heavyweight Process. Processes contain information about program resources and program execution state, including: Process ID, process group ID, user ID
E N D
Process Vs Thread • A Process is an executable program with single thread of control. • It’s is also called as Heavyweight Process. • Processes contain information about program resources and program execution state, including: • Process ID, process group ID, user ID • Environment • Working directory • Program instructions • Registers • Stack • Heap • File descriptors • Signal actions • Shared libraries • Inter-process communication tools (such as message queues, pipes, semaphores, or shared memory).
Threads • A thread is defined as an independent stream of instructions that can be scheduled to run by the operating system • A process can have multiple threads, each of which has its own flow of control (program counter) and its own stack. • Thread is also called lightweight process because it duplicates only the bare essential resources (from the process that created it)that enable it to exist as executable code. • Thread are generally used when concurrent execution of the same complex data structure is needed. • Where as, processes can be used for less tightly coupled applications, where some data is passed between the processes. • Multithreaded programs increase performance if multiprocessor or multi-core systems are used.
Process Vs Thread THREADS WITHIN A UNIX PROCESS UNIX PROCESS
What are Pthreads? • In order to take full advantage of the capabilities provided by threads, a standardized programming interface was required. • For UNIX systems, this interface has been specified by the IEEE POSIX 1003.1c standard (1995). • Implementations adhering to this standard are referred to as POSIX threads, or Pthreads. • Pthreads are defined as a set of C language programming types and procedure calls are implemented in “pthread.h” header file.
Why Pthreads? • The primary motivation for using Pthreads is to realize potential program performance gains. • When compared to the cost of creating and managing a process, a thread can be created with much less operating system overhead. • Managing threads requires fewer system resources than managing processes. • All threads within a process share the same address space. • Inter-thread communication is more efficient than inter-process communication.
Thread Creation • pthread_create creates a new thread and makes it executable. • Syntax • int Pthread_create(pthread *thread, /*new thread id*/ const pthread_attr_t *attr, /*attributes (or NULL)*/ void *(start_func)(void *), /*starting function */ void *arg /*arg to starting function*/ ); • pthread_create arguments: • thread: Unique identifier for the new thread returned by the subroutine. • attr: This can be used to set thread attributes. You can specify a thread attributes object, or NULL for the default values. • start_routine: the C routine that the thread will execute once it is created. • arg: A single argument that may be passed to start_routine. It must be passed by reference as a pointer cast of type void. NULL may be used if no argument is to be passed.
Example: Pthread Creation and Termination main(){ pthread_t thread1; char *message1 = "Thread 1 says hi"; pthread_create( &thread1, NULL,print, (void*) message1); exit(0); } void *print( void *ptr ) { char *message; message = (char *) ptr; printf("%s \n", message); }
Thread Creation: example 1 output Thread 1 says hi Thread 2 says hi void *thread_func(void * ptr) { char *message; message = (char *)ptr; printf("%s\n",message); return NULL; } int main() { pthread_t thread1, thread2; char *message1 = "Thread 1 says hi"; char *message2 = "Thread 2 says hi"; pthread_create(&thread1,NULL,thread_func,(void *)message1); pthread_create(&thread2,NULL,thread_func,(void *)message2); pthread_join( thread1, NULL); pthread_join( thread2, NULL); }
Pthread_join() • A thread can wait for another thread to terminate and get its exit status with this procedure call. • Syntax • int pthread_join( pthread_t thread_id, /*ID of thread to join*/ void **status_ptr /* returned exit status (if not NULL arg)*/ );
Example 2 OUTPUT Thread 1 says 1 Thread 2 says 2 Thread 2 says 3 Thread 1 says 4 Thread 2 says 5 Thread 2 says 6 Thread 1 says 7 Thread 2 says 8 Thread 2 says 9 Thread 1 says 10 Thread 2 says 11 Thread 2 says 12 static long x = 0; void * thread_func(void *arg){ while(1){ printf("Thread 2 says %ld\n",++x); sleep(1); } } int main(){ pthread_t tid; pthread_create(&tid,NULL,thread_func,NULL); while(x < 10) { printf("Thread 1 says %ld\n",++x); sleep(2); } return 0; }
Example to show exit status of a thread Output Thread 1 says 1 Thread 2 says 2 Thread 2 says 3 Thread 1 says 4 Thread 2 says 5 Thread 2 says 6 Thread 1 says 7 Thread 1 says 8 Thread 1 says 9 Thread 1 says 10 Exit status of thread 2 is 7 static long x = 0; void * thread_func(void *arg){ while(x < (long)arg) { printf("Thread 2 says %ld\n",++x); sleep(1); } return (void *)x; } int main(){ pthread_t tid; void *status; pthread_create(&tid,NULL,thread_func,(void*)7); while(x < 10) { printf("Thread 1 says %ld\n",++x); sleep(2); } pthread_join(tid,&status); printf("Exit status of thread 2 is %ld\n",(long)status); return 0; }
Thread_Array Output 1 2 3 4 5 void *thread_func(void * ptr) { long *message; message = (long *)ptr; printf("%ld\n",*message); return NULL; } int main(){ pthread_t thread[5]; long a[5] = {1,2,3,4,5}; int i; for(i=0;i<5;i++) pthread_create(&thread[i],NULL,thread_func,(void *)&a[i]); for(i=0;i<5;i++) pthread_join( thread[i], NULL); }
Thread Synchronization • Mutual exclusion is provided by the following system calls : • Pthread_mutex_lock() • Pthread_mutex_unlock() • pthread_mutex_lock( pthread_mutex_t *mutex /*mutex to lock*/ ); • Pthread_mutex_unlock( pthread_mutex_t *mutex /*mutex to unlock*/ ); static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
Example code on mutual exclusion static long x = 0; static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; void * thread_func(void *p){ int done=0; while(1){ pthread_mutex_lock(&mtx); if(x >= (long)p) done = 1; pthread_mutex_unlock(&mtx); if(done) break; pthread_mutex_lock(&mtx); printf("thread 2 says %ld\n",++x); pthread_mutex_unlock(&mtx); sleep(1); } return (void *)x; }
int main(){ pthread_t tid; void *status; int done=0; long a = 6; pthread_create(&tid,NULL,thread_func,(void *)a); while(1) { pthread_mutex_lock(&mtx); if(x >= 10) done = 1; pthread_mutex_unlock(&mtx); if(done) break; pthread_mutex_lock(&mtx); printf("Thread 1 says %ld\n",++x); pthread_mutex_unlock(&mtx); sleep(2); } pthread_join(tid,&status); printf("status of thread 2 is %ld\n",(long)status); return 0; }
int main() { pthread_t tid; void *status; assert(sizeof(long) <= sizeof(void* )); pthread_create(&tid,NULL,thread_func,(void *)6); while(get_and_incr_x(0) < 10) { printf("Thread 1 says %ld \n",get_and_incr_x(1)); sleep(2); } pthread_join(tid,&status); printf("status of thread 2 is %ld\n",(long)status); return 0; }
static long get_and_incr_x(long incr) { static long x = 0; static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; long rtn; pthread_mutex_lock(&mtx); rtn = x +=incr; pthread_mutex_unlock(&mtx); return rtn; } void * thread_func(void *p) { int done=0; while(get_and_incr_x(0) < (long)p) { printf("thread 2 says %ld\n",get_and_incr_x(1)); sleep(1); } return (void *)get_and_incr_x(0); }
Condition Variable • The condition variable mechanism allows threads to suspend execution and relinquish the processor until some condition is true. • A condition variable must always be associated with a mutex to avoid contention of shared resources. • A condition variable is a variable of type pthread_cond_t and is used with the appropriate functions for waiting and later, process continuation.
pthread_cond_wait - unlocks the mutex and waits for the condition variable cond to be signaled. • pthread_cond_signal - restarts one of the threads that are waiting on the condition variable cond. • pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
Syntax of condition variable • Pthread_cond_signal( pthread_cond_ *cond //cond variable ); • Pthread_cond_wait( pthread_cond_t *cond, //cond variable pthread_mutex_t *mutex //mutex );