



Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Multithreaded Models, User and Kernel level threads, Solaris 2 threads model, POSIX thread, The pthread library, Sample code, Creating a thread, Joining and terminating a thread. Above mentioned are key points of this lecture handout. Virtual University handout for introduction to operating system are in detail and explanatory.
Typology: Study notes
1 / 7
This page cannot be seen from the preview
Don't miss anything!




Operating Systems--[CS-604] Lecture No.
UNIX/Linux manual pages pthread_create(), pthread_join(), and pthread_exit() calls Chapter 5 of the textbook Lecture 13 on Virtual TV
User- and Kernel –level threads Multi-threading models Solaris 2 threads model POSIX threads (the pthread library) Sample code
Support for threads may be provided at either user level for user threads or by kernel for kernel threads. User threads are supported above kernel and are implemented by a thread library at the user level. The library provides support for thread creation, scheduling, and management with no support from the kernel. Since the kernel is unaware of user-level threads, all thread creation and scheduling are done in the user space without the need for kernel intervention, and therefore are fast to create and manage. If the kernel is single threaded, then any user level thread performing a blocking system call will cause the entire process to block, even if other threads are available to run within the application. User thread libraries include POSIX Pthreads , Solaris 2 UI-threads, and Mach C- threads. Kernel threads are supported directly by the operating system. The kernel performs the scheduling, creation, and management in kernel space; the kernel level threads are hence slower to create and manage, compared to user level threads. However since the kernel is managing threads, if a thread performs a blocking system call, the kernel can schedule another thread in the application for execution. Windows NT, Windowss 2000, Solaris, BeOS and Tru64 UNIX support kernel threads.
There are various models for mapping user-level threads to kernel-level threads. We describe briefly these models, their main characteristics, and examples.
Figure 13.1 Many –to-One Model
Figure 13.2 One-to-One Model
Creating a Thread You can create a threads by using the pthread_create() call. Here is the syntax of this call.
int pthread_create(pthread_t threadp, const pthread_attr_t attr, void (routine)(void *), arg *arg);
where, ‘threadp’ contains thread ID (TID) of the thread created by the call, ‘attr’ is used to modify the thread attributes (stack size, stack address, detached, joinable, priority, etc.), ‘routine’ is the thread function, and ‘arg’ is any argument we want to pass to the thread function. The argument does not have to be a simple native type; it can be a ‘struct’ of whatever we want to pass in. The pthread_create() call fails and returns the corresponding value if any of the following conditions is detected: EAGAIN The system-imposed limit on the total number of threads in a process has been exceeded or some system resource has been exceeded (for example, too many LWPs were created). EINVAL The value specified by ‘attr’ is invalid. ENOMEM Not enough memory was available to create the new thread. You can do error handling by including the <errno.h> file and incorporating proper error handling code in your programs.
Joining a Thread You can have a thread wait for another thread within the same process by using the pthread_join() call. Here is the syntax of this call.
int pthread_join(pthread_t aThread, void **statusp);
where, ‘aThread’ is the thread ID of the thread to wait for and ‘statusp’ gets the return value of pthread_exit() call made in the process for whom wait is being done. A thread can only wait for a joinable thread in the same process address space; a thread cannot wait for a detached thread. Multiple threads can join with a thread but only one returns successfully; others return with an error that no thread could be found with the given TID
Terminating a Thread You can terminate a thread explicitly by either returning from the thread function or by using the pthread_exit() call. Here is the syntax of the pthread_exit() call.
void pthread_exit(void *valuep);
where, ‘valuep’ is a pointer to the value to be returned to the thread which is waiting for this thread to terminate (i.e., the thread which has executed pthread_join() for this thread). A thread also terminates when the main thread in the process terminates. When a thread terminates with the exit() system call, it terminates the whole process because the purpose of the exit() system call is to terminate a process and not a thread.
The following code shows the use of the pthread library calls discussed above. The program creates a thread and waits for it. The child thread displays the following message on the screen and terminates. Hello, world! ... The threaded version.
As soon as the child thread terminates, the parent comes out of wait, displays the following message and terminates.
Exiting the main function.
#include <stdio.h> #include <stdlib.h> #include <pthread.h> /* Prototype for a function to be passed to our thread / void MyThreadFunc(void arg); int main() { pthread_t aThread; / Create a thread and have it run the MyThreadFunction / pthread_create(&aThread, NULL, MyThreadFunc, NULL); / Parent waits for the aThread thread to exit / pthread_join(aThread, NULL); printf ("Exiting the main function.\n"); return 0; } void MyThreadFunc(void* arg) { printf ("Hello, world! ... The threaded version.\n"); return NULL; }
The following session shows compilation and execution of the above program. Does the output make sense to you?
$ gcc hello.c –o hello –lpthread –D_REENTRANT $ hello Hello, world! ... The threaded version. Exiting the main function. $
Note that you need to take the following steps in order to be able to use the pthread library.
pthread_t threads[NUM_THREADS]; int *taskids[NUM_THREADS]; int rc, t, sum;
sum=0; messages[0] = "English: Hello World!"; messages[1] = "French: Bonjour, le monde!"; messages[2] = "Spanish: Hola al mundo"; messages[3] = "Klingon: Nuq neH!"; messages[4] = "German: Guten Tag, Welt!"; messages[5] = "Russian: Zdravstvytye, mir!"; messages[6] = "Japan: Sekai e konnichiwa!"; messages[7] = "Latin: Orbis, te saluto!";
for(t=0; t<NUM_THREADS; t++) { sum = sum + t; thread_data_array[t].thread_id = t; thread_data_array[t].sum = sum; thread_data_array[t].message = messages[t]; printf("Creating thread %d\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &thread_data_array[t]); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } pthread_exit(NULL); }
The above code was taken from the following website. http://www.llnl.gov/computing/tutorials/pthreads/samples/hello_arg2.c