Tutorial 4
In this tutorial session we’ll see Threads.
Threads
Process Processes contain information about program resources and program execution state, including: Process ID, process group ID, user ID, and group ID Program code (text) Registers Stack (for temporary data) Heap (for dynamic memory allocations) Shared libraries
UNIX Process
Threads In the UNIX environment a thread: Exists within a process and uses the process resources Has its own independent flow of control . Duplicates only the essential resources it needs. May share the process resources with other threads that act equally independently (and dependently). Dies if the parent process dies - or something similar
Cont. This independent flow of control is accomplished because a thread maintains its own: Program Counter Stack Space Register Set (i.e. space to store register values when not on the CPU) Priority (used for scheduling of CPU time). Thread ID
UNIX Thread
Pthreads POSIX Threads: is a POSIX standard for threads. The standard defines an API for creating and manipulating threads. Pthreads : Libraries implementing the POSIX Threads standard. Defined as a set of C language programming types and procedure calls, implemented with a pthread.h header file. Pthreads are most commonly used on Unix-like systems, but Microsoft Windows implementations also exist. POSIX (IPA: /ˈpɒzɪks/) or "Portable Operating System Interface" is the collective name of a family of related standards specified by the IEEE to define the application programming interface (API) for software compatible with variants of the Unix operating system, although the standard can apply to any operating system.
Creating threads Initially, your main() program comprises a single, default thread. All other threads must be explicitly created by the programmer.
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.
Creating threads (cont.) pthread_create() arguments: thread: An identifier for the new thread returned by the subroutine. attr: An attribute object that may be used to set thread attributes. You can specify a thread attributes object, or NULL for the default values. Thread attributes includes stack size and scheduling information. 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.
Creating threads (cont.) Return value: If successful, the pthread_create() routine shall return zero otherwise, an error number shall be returned to indicate the error.
Terminating threads There are several ways in which a Pthread may be terminated: The thread returns from its starting routine. The thread makes a call to the pthread_exit() subroutine. The thread is canceled by another thread via the pthread_cancel routine. The entire process is terminated due to a call to either the exec or exit subroutines.
Joining Threads int pthread_join(pthread_t thread, void ** thread_return); 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.
Joining Threads PARAMETERS thread thread_return Is the thread to wait for. thread_return If thread_return is not NULL, the return value of thread is stored in the location pointed to by thread_return
Example 1: void * thread2() { while(1){ printf("How are you?\n"); } Two threads displaying two strings “Hello” and “How are you?” independent of each other. #include <stdio.h> #include <pthread.h> #include <stdlib.h> void * thread1() { while(1){ printf("Hello!!\n"); }
cont. int main() { int status; pthread_t tid1,tid2; pthread_create(&tid1,NULL,thread1,NULL); pthread_create(&tid2,NULL,thread2,NULL); pthread_join(tid1,NULL); pthread_join(tid2,NULL); return 0; }
Example /* pthread.c by detour@metalshell.com * Create multiple POSIX thread processes and wait for * each one to complete. * * http://www.metalshell.com/ */ #include <unistd.h> #include <pthread.h> #include <stdio.h> #include <time.h> #define NUM_THREADS 10
void. thread_function(void. arg) { fprintf(stdout, "Thread: %d running void *thread_function(void *arg) { fprintf(stdout, "Thread: %d running.\n", (int)arg); // Sleep for arg+1 seconds to verify pthread_join. sleep((int)arg+1); fprintf(stdout, "Thread: %d done.\n", (int)arg); pthread_exit(0); }
int main() { int cnt; pthread_t p_thread[NUM_THREADS]; for(cnt = 0; cnt < NUM_THREADS; cnt++) /* Returns 0 on successful creation of the thread. The second parameter, left NULL for this example, allows for options like CPU scheduling to be set. */ if(pthread_create(&p_thread[cnt], NULL, thread_function, (void *)cnt) != 0) fprintf(stderr, "Error creating the thread");
// Cycle through each thread and wait until it is completed. for(cnt = 0; cnt < NUM_THREADS; cnt++) { // Waits for p_thread[cnt] to finish. pthread_join(p_thread[cnt], NULL); } fprintf(stdout, "All threads completed.\n"); return 0;