38
Threads

Tutorial4 Threads

Embed Size (px)

Citation preview

Page 1: Tutorial4  Threads

Threads

Page 2: Tutorial4  Threads

Process• Processes contain information about program resources

and program execution state, including: – Process ID, process group ID, user ID, and group 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).

Page 3: Tutorial4  Threads

UNIX Process

Page 4: Tutorial4  Threads

Threads

• Threads use and exist within these process resources, yet are able to be scheduled by the operating system and run as independent entities largely because they duplicate only the bare essential resources that enable them to exist as executable code.

Page 5: Tutorial4  Threads

Cont.

• This independent flow of control is accomplished because a thread maintains its own: – Stack pointer – Registers – Scheduling properties (such as policy or priority) – Set of pending and blocked signals – Thread specific data (thread ID)

Page 6: Tutorial4  Threads

UNIX Thread

Page 7: Tutorial4  Threads

UNIX Threads• In the UNIX environment a thread: – Exists within a process and uses the process resources – Has its own independent flow of control as long as its

parent process exists and the OS supports it – Duplicates only the essential resources it needs to be

independently schedulable – May share the process resources with other threads

that act equally independently (and dependently) – Dies if the parent process dies - or something similar – Is "lightweight" because most of the overhead has

already been accomplished through the creation of its process.

Page 8: Tutorial4  Threads

Pthreads

• A thread library that provides the programmer an API for creating and managing threads

• Pthreads refers to the POSIX standards defining an API for thread creation and synchronization

Page 9: Tutorial4  Threads

Pthreads

• Pthreads are defined as a set of C language programming types and procedure calls, implemented with a pthread.h header/include file and a thread library

Page 10: Tutorial4  Threads

Creating threads

• Initially, your main() program comprises a single, default thread. All other threads must be explicitly created by the programmer.

Page 11: Tutorial4  Threads

Creating threads (cont.)

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void*), void *arg);

Description:• pthread_create() creates a new thread and

makes it executable. This routine can be called any number of times from anywhere within your code.

Page 12: Tutorial4  Threads

Creating threads (cont.)• pthread_create() arguments: – thread: An opaque, unique identifier for the new

thread returned by the subroutine. – attr: An opaque attribute object that may 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.

Page 13: Tutorial4  Threads

Cont.

• Return value:– If successful, the pthread_create() routine shall

return zero– other- wise, an error number shall be returned to

indicate the error.

Page 14: Tutorial4  Threads

Thread attributes

• Thread attributes include (define members of the struct pthread_attr_t):– detached state– scheduling policy– scheduling parameter – inheritsched attribute– Scope– guard size – stack address– stack size

Page 15: Tutorial4  Threads

Scheduling threads

• After a thread has been created, how do you know when it will be scheduled to run by the operating system?

– It is up to the implementation and/or operating system to decide where and when threads will execute.

Page 16: Tutorial4  Threads

Terminating threads

• pthread_exit() is used to explicitly exit a thread.

• If main() finishes before the threads it has created, and exits with pthread_exit(), the other threads will continue to execute. Otherwise, they will be automatically terminated when main() finishes.

Page 17: Tutorial4  Threads

Joining Threads

int pthread_join(pthread_t thread, void **value_ptr);

Description:• The pthread_join() function shall suspend

execution of the calling thread until the target thread terminates.

• Return value: – If successful, the pthread_join() function shall return

zero; otherwise, an error number shall be returned to indicate the error.

Page 18: Tutorial4  Threads

Joining Threads (Cont.)

Page 19: Tutorial4  Threads

Example -1-

Page 20: Tutorial4  Threads

#include <pthread.h>#include <stdio.h>#define NUM_THREADS 5void *PrintHello(void *threadid){ int tid; tid = (int)threadid; printf("Hello World! It's me, thread #%d!\n", tid); pthread_exit(NULL);}int main (int argc, char *argv[]){ pthread_t threads[NUM_THREADS]; int rc, t; for(t=0; t<NUM_THREADS; t++){ printf("In main: creating thread %d\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } pthread_exit(NULL);}

Page 21: Tutorial4  Threads

Code Explanation

Page 22: Tutorial4  Threads

• Defines an array of threads (note: threads are not yet created!) of opaque type pthread_t

• In for loop:– Threads will be created using

pthread_create. The routine PrintHello() is the starting routine for all newly created threads

– The returned value for each thread creation will be checked and prints and error message if the returned value is not zero

int main (int argc, char *argv[]){ pthread_t threads[NUM_THREADS]; int rc, t; for(t=0; t<NUM_THREADS; t++){ printf("In main: creating thread %d\

n", t); rc = pthread_create(&threads[t],

NULL, PrintHello, (void *)t); if (rc){ printf("ERROR; return code from

pthread_create() is %d\n", rc); exit(-1); } }

Page 23: Tutorial4  Threads

Cont.

• The routine PrintHello will simply print,“Hello World! It’s me, thread# threadnum

• It will then terminate the thread using pthread_exit.

void *PrintHello(void *threadid)

{ int tid; tid = (int)threadid; printf("Hello World! It's

me, thread #%d!\n", tid);

pthread_exit(NULL);}

Page 24: Tutorial4  Threads

Possible Outputs

In main: creating thread 0In main: creating thread 1Hello World! It's me, thread#0!In main: creating thread 2 Hello World! It's me, thread #1!Hello World! It's me, thread #2!In main: creating thread 3In main: creating thread 4 Hello World! It's me, thread #3!Hello World! It's me, thread #4!

In main: creating thread 0In main: creating thread 1In main: creating thread 2 In main: creating thread 3In main: creating thread 4 Hello World! It's me, thread#0!Hello World! It's me, thread #1!Hello World! It's me, thread #2!Hello World! It's me, thread #3!Hello World! It's me, thread #4!

Page 25: Tutorial4  Threads

Example -2-

Page 26: Tutorial4  Threads

#include <stdio.h>#include <stdlib.h>#include <pthread.h>void *print_message_function( void *ptr );

main(){

pthread_t thread1, thread2;char *message1 = "Thread 1";char *message2 = "Thread 2";int iret1, iret2;/* Create independent threads each of which will execute function */iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);/* Wait till threads are complete before main continues. Unless we *//* wait we run the risk of executing an exit which will terminate *//* the process and all threads before the threads have completed. */pthread_join( thread1, NULL);pthread_join( thread2, NULL);

printf("Thread 1 returns: %d\n",iret1);printf("Thread 2 returns: %d\n",iret2);exit(0);

}

void *print_message_function( void *ptr ){

char *message;message = (char *) ptr;printf("%s \n", message);

}

Page 27: Tutorial4  Threads

Code Explanation

Page 28: Tutorial4  Threads

• Defines an array of threads (note: threads are not yet created!) of opaque type pthread_t

• Threads will be created using pthread_create(). The routine print_message_function() is the starting routine for the two newly created routines. Notice that an argument was sent to print_message_function() as an argument to pthread_create()

• The two threads newly created will be joined using pthread_join()

main(){pthread_t thread1, thread2;char *message1 = "Thread 1";char *message2 = "Thread 2";int iret1, iret2;iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);

pthread_join( thread1, NULL);pthread_join( thread2, NULL);

printf("Thread 1 returns: %d\n",iret1);printf("Thread 2 returns: %d\n",iret2);exit(0);}

Page 29: Tutorial4  Threads

Cont.

• The routine PrintHello will simply print,“Hello World! It’s me, thread# threadnum

• It will then terminate the thread using pthread_exit.

void * print_message_function( void *ptr ){char *message;message = (char *) ptr;printf\n", message);} ("%s

Page 30: Tutorial4  Threads

Output

Thread 1Thread 2Thread 1 returns : 0Thread 2 returns : 0

Page 31: Tutorial4  Threads

Example -3-

Example 1 while using pthread_join()

Page 32: Tutorial4  Threads

#include <pthread.h>#include <stdio.h>#define NUM_THREADS 5void *PrintHello(void *threadid){ int tid; tid = (int)threadid; printf("Hello World! It's me, thread #%d!\n", tid); pthread_exit(NULL);}int main (int argc, char *argv[]){ pthread_t threads[NUM_THREADS]; int rc, t; for(t=0; t<NUM_THREADS; t++){ printf("In main: creating thread %d\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } pthread_join(threads[t], NULL) ;} pthread_exit(NULL);}

Page 33: Tutorial4  Threads

Possible Outputs

In main: creating thread 0Hello World! It's me, thread#0!In main: creating thread 1Hello World! It's me, thread #1!In main: creating thread 2 Hello World! It's me, thread #2!In main: creating thread 3Hello World! It's me, thread #3!In main: creating thread 4 Hello World! It's me, thread #4!

Page 34: Tutorial4  Threads

Example -4-

Page 35: Tutorial4  Threads

#include <pthread.h>#include <stdlib.h>#include <stdio.h>

void *thread_func( void *vptr_args );

int main( void ){int i, j;pthread_t thread;

pthread_create( &thread, NULL, &thread_func, NULL );

for( j= 0; j < 6; ++j ){fprintf( stdout, "a\n" );

for( i= 99999999; i; --i ); /* use some CPU time */}

pthread_join( thread, NULL );exit( EXIT_SUCCESS );

}void *thread_func( void *vptr_args ){

int i, j;

for( j= 0; j < 6; ++j ){fprintf( stderr, " b\n" );

for( i= 99999999; i; --i ); /* use some CPU time */}return NULL;

}

Page 36: Tutorial4  Threads

Output

ab

aa

ba

ba

bb

ab

• What happens if we change the position of pthread_join() in the code?

Page 37: Tutorial4  Threads

#include <pthread.h>#include <stdlib.h>#include <stdio.h>

void *thread_func( void *vptr_args );

int main( void ){int i, j;pthread_t thread;

pthread_create( &thread, NULL, &thread_func, NULL ); pthread_join( thread, NULL );

for( j= 0; j < 6; ++j ){fprintf( stdout, "a\n" );

for( i= 99999999; i; --i ); /* use some CPU time */}

/* Previous position in codepthread_join( thread, NULL ); */exit( EXIT_SUCCESS );

}void *thread_func( void *vptr_args ){

int i, j;

for( j= 0; j < 6; ++j ){fprintf( stderr, " b\n" );

for( i= 99999999; i; --i ); /* use some CPU time */}return NULL;

}

Page 38: Tutorial4  Threads

Output

bbbbbb

aaaaaa

• What happened?