Threads 2x[1]

  • 1,498 views
Uploaded on

 

More in: Education , Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,498
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
123
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Single Thread vs. Multithreads In traditional operating systems, each process has an address space and a single thread of control There are frequently solutions in which it is desirable to have multiple Multithreaded Programming threads of control in the same address space running concurrently, as though they are (almost) separate processes (except for the shared address space).Operating System Concepts – 8th Edition Modified by 4.1 M.Rebaudengo - 2010 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.3 Silberschatz, Galvin and Gagne ©2009 Processes and Threads Thread Model Process abstraction combines two concepts (a) Three processes each with one thread Concurrency (b) One process with three threads Each process is a sequential execution stream of instructions Protection Each process defines an address space Address space identifies all addresses that can be touched by the program Threads Key idea: separate the concepts of concurrency from protection A thread is a sequential execution stream of instructions A process defines the address space that may be shared by multiple threads Threads can execute on different cores on a multicore CPU (parallelism for performance) and can communicate with other threads by updating memory.Operating System Concepts – 8th Edition 4.2 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.4 Silberschatz, Galvin and Gagne ©2009
  • 2. Example of multithreads (I) How Can it Help? Consider how a Web server can improve performance and interactivity by Consider a Web server using threads. Create a number of threads, and for each thread do When a Web server receives requests for images and pages from many get network message from client clients, it serves each request (from each client) with a different thread get URL data from disk The process that receives all the requests, creates a new separate thread for each request received send data over network This new thread sends the required information to the remote client. While this thread is doing its task, the original thread is free to accept What did we gain? more requests Web servers are multiprocessor systems that allow for concurrent completion of several requests, thus improving throughput and response time.Operating System Concepts – 8th Edition 4.5 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.7 Silberschatz, Galvin and Gagne ©2009 The Case for Threads Overlapping Requests (Concurrency) Consider a Web server Request 1 Request 2 Thread 1 Thread 2 get network message (URL) from client get network message (URL) from client get URL data from disk get URL data from disk compose response get network message (URL) from client send response get URL data from disk How well does this web server perform? (disk access latency) (disk access latency) send data over network send data over network Total time is less than request 1 + request 2 TimeOperating System Concepts – 8th Edition 4.6 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.8 Silberschatz, Galvin and Gagne ©2009
  • 3. Example of multithreads (II) Multithreads Consider a word processor composed of three threads: Different threads in a process are not as independent as different a thread interacts with the user processes: a thread handles reformatting in the background processing the All threads have exactly the same address space, which means that document they share the same global variables. a thread performs spell checking a thread handle the disk backups without interfering with the other two in order to automatically save the entire file every few minutes to protect the user against losing the work in the event of program crash.Operating System Concepts – 8th Edition 4.9 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.11 Silberschatz, Galvin and Gagne ©2009 Process vs. Threads Threads A process has an address space containing program text and data, as well A thread represents an abstract entity that executes a sequence of instructions other resources like, open files, child processes, pending alarms, signal It has its own set of CPU registers handlers, accounting information, etc. It has its own stack A thread of execution has a program counter, registers and a stack. There is no thread-specific heap or data segment (unlike process) Threads are lightweight Processes are used to group resources together Creating a thread more efficient than creating a process. Threads are the entities scheduled for execution on the CPU. Communication between threads easier than btw. processes. Context switching between threads requires fewer CPU cycles and memory references than switching processes. Threads only track a subset of process state (share list of open files, pid, …).Operating System Concepts – 8th Edition 4.10 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.12 Silberschatz, Galvin and Gagne ©2009
  • 4. Single and Multithreaded Processes Performance Benefits It takes far less time to create a new thread in an existing process than to create a new process It takes less time to terminate a thread than a process It takes less time to switch between 2 threads within the same process than to switch between processes Threads between the same process share memory and files: they can communicate with each other without invoking the kernel. If there is an application od function that should be implemented as a set of related units of execution, it is far more efficient to do so as a collection of threads rather than a collection of separate processes.Operating System Concepts – 8th Edition 4.13 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.15 Silberschatz, Galvin and Gagne ©2009 Benefits Parallel Execution on a Multicore System Responsiveness When one thread is blocked, your browser still responds E.g. download images while allowing your interaction Resource Sharing Share the same address space Reduce overhead (e.g. memory) Economy Creating a new process costs memory and resources E.g. in Solaris, 30 times slower in creating process than thread Scabality / Parallelization Threads can be executed in parallel on multiple processors Increase concurrency and throughputOperating System Concepts – 8th Edition 4.14 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.16 Silberschatz, Galvin and Gagne ©2009
  • 5. Multicore Programming Latency and Throughput Multicore systems putting pressure on programmers, challenges include Latency: time to complete an operation Dividing activities Throughput: work completed per unit time. Balance Data splitting Data dependency Testing and debuggingOperating System Concepts – 8th Edition 4.17 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.19 Silberschatz, Galvin and Gagne ©2009 How Can it Help? Relationship between Latency and Throughput How can this code take advantage of 2 threads? Latency and bandwidth only loosely coupled for(k = 0; k < n; k++) Henry Ford: assembly lines increase bandwidth without reducing latency a[k] = b[k] * c[k] + d[k] * e[k]; My factory takes 1 day to make a Model-T Ford. Rewrite this code fragment as: But I can start building a new car every 10 minutes do_mult(l, m) { At 24 hrs/day, I can make 24 * 6 = 144 cars per day for(k = l; k < m; k++) A special order for 1 green car, still takes 1 day a[k] = b[k] * c[k] + d[k] * e[k]; Throughput is increased, but latency is not. } Latency reduction is difficult main() { Often, one can buy bandwidth CreateThread(do_mult, 0, n/2); E.g., more memory chips, more disks, more computers CreateThread(do_mult, n/2, n); Big server farms (e.g., google) are high bandwidthOperating System Concepts – 8th Edition 4.18 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.20 Silberschatz, Galvin and Gagne ©2009
  • 6. Latency and bandwith The boss/worker model Multiplying vector example: reduced latency Web server example: increased throughput What is “High speed Internet?” Program Resources Low latency: needed to interactive gaming Workers taskX taskX Files High bandwidth: needed for downloading large files. Boss Databases taskY taskY main ( ) Input (Stream) main ( ) Disks taskZ taskZ Special DevicesOperating System Concepts – 8th Edition 4.21 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.23 Silberschatz, Galvin and Gagne ©2009 Thread Programming models Example main() /* the boss */ Boss/worker { Peer model forever { get a request; Pipeline switch( request ) Thread pool case X: thread_create(....,taskX); case Y: thread_create(....,taskY); .... } } taskX() /* worker */ { perform the task, sync if accessing shared resources } taskY() /* worker */ { perform the task, sync if accessing shared resources }Operating System Concepts – 8th Edition 4.22 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.24 Silberschatz, Galvin and Gagne ©2009
  • 7. The peer model A thread pipeline Program Filter Threads Program Resources Stage 1 Stage 1 Stage 2 Stage 2 Stage 3 Stage 3 Workers Input Input taskX taskX Files Input (Stream) (static) (static) Databases taskY taskY Files Files Files Resources Databases Databases Databases Disks taskZ taskZ Disks Disks Disks Special Devices Special Devices Special Devices Special DevicesOperating System Concepts – 8th Edition 4.25 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.27 Silberschatz, Galvin and Gagne ©2009 Example Example main() { main() thread_create(....,stage1); { thread_create(....,stage2); thread_create(....,task1); .... thread_create(....,task2); wait for all pipeline threads to finish .... do any cleanup signal all workers to start } stage1() { wait for all workers to finish get next input for the program do any cleanup do stage 1 processing of the input } pass result to next thread in pipeline } } task1() /* worker */ stage2(){ { get input from previous thread in pipeline do stage 2 processing of the input wait for start pass result to next thread in pipeline perform the task, sync if accessing shared resources } } stageN() task2() /* worker */ { { get input from previous thread in pipeline wait for start do stage N processing of the input pass result to program output. perform the task, sync if accessing shared resources } }Operating System Concepts – 8th Edition 4.26 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.28 Silberschatz, Galvin and Gagne ©2009
  • 8. Thread pool Thread Control Block (TCB) Runtime overhead of creating thread can be solved by thread pool the Each thread has: main thread creates all worker threads at program initialization and each an identifier, worker thread suspends itself immediately for a wakeup call from boss. a set of registers (including the program counter) Typically there are more tasks than threads. Tasks are organized in queue. As soon as a thread completes its task, it will request the next task from the a set of attributes including the state, the stack size, scheduling queue. parameters, etc. The number of threads is a parameter that can be tuned to provide the best performance. The number of threads could be dynamic based on the number of waiting tasks.Operating System Concepts – 8th Edition 4.29 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.31 Silberschatz, Galvin and Gagne ©2009 Thread Model Stacks Each thread has its own stack: Each stack contains one frame for each procedure called but not yet returned from This frame contains the procedure’s local variables and the return address to use when the procedure call has finished Each thread will call different procedures and thus have a different execution history. Items shared by all threads in a process Items private to each threadOperating System Concepts – 8th Edition 4.30 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.32 Silberschatz, Galvin and Gagne ©2009
  • 9. Threads vs. Processes Threads’ Life Cycle Threads (just like processes) go through a sequence of start, ready, running, Threads Processes waiting, and done states A process has code/data/heap & A thread has no data segment or other segments heap There must be at least one thread in A thread cannot live on its own, it must live within a process a process Start Start Done Done Threads within a process share There can be more than one thread in a process, the first thread calls code/data/heap, share I/O, but each main and has the process’s stack has its own stack and registers If a thread dies, its stack is If a process dies, its resources are reclaimed reclaimed and all threads die Ready Ready Running Running Inter-thread communication via Inter-process communication via OS memory. and data copying. Each thread can run on a different Each process can run on a different physical processor physical processor Waiting Waiting Inexpensive creation and context Expensive creation and context switch switchOperating System Concepts – 8th Edition 4.33 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.35 Silberschatz, Galvin and Gagne ©2009 Implementing Threads Exercise Process’s TCB for address space Context switch time for which entity is greater? Processes define an address Thread1 space; threads share the address 1. Process mapped segments space PC PC 2. Thread SP DLL’s SP Process Control Block (PCB) State State Heap contains process-specific Registers Registers information …… Owner, PID, heap pointer, priority, active thread, and pointers to thread information TCB for Stack – thread2 Thread2 Thread Control Block (TCB) contains thread-specific information PC PC Stack – thread1 Stack pointer, PC, thread state SP SP (running, …), register values, a State State Initialized data pointer to PCB, … Registers Registers …… CodeOperating System Concepts – 8th Edition 4.34 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.36 Silberschatz, Galvin and Gagne ©2009
  • 10. Exercise Exercise #include <pthread.h> Threads have their own…? #include <stdio.h> 1. CPU #include <sys/types.h> 2. Address space int value = 0; /* this data is shared by the thread(s) */ 3. PCB void *runner(void *param); /* the thread */ 4. Stack 5. Registers } void *runner(void *param) { value = 5; pthread_exit(0); }Operating System Concepts – 8th Edition 4.37 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.39 Silberschatz, Galvin and Gagne ©2009 Exercise Exercise (cont.) Threads have the same scheduling states as processes int main(int argc, char *argv[]) 1. True { 2. False pid_t pid; pthread_t tid; /* the thread identifier */ pthread_attr_t attr; /* set of attributes for the thread */ pid = fork() if (pid == 0) { /* child process */ pthread_attr_init(&attr); pthread_create(&tid,&attr,runner,NULL); /* now wait for the thread to exit */ pthread_join(tid,NULL); printf("CHILD: value = %dn",value); 5 } else if (pid > 0) { /* parent process */ wait(NULL); printf("PARENT: value = %dn",value); 0 }Operating System Concepts – 8th Edition 4.38 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.40 Silberschatz, Galvin and Gagne ©2009
  • 11. Thread Libraries User-Level Thread Thread library provides programmer with API for creating and managing threads Two primary ways of implementing User-Level Threads (ULT): library entirely in user space (invoking a function in the library results in a local function call in user space and not a system call) Kernel-Level Threads (KLT): Kernel-level library supported by the OS (system call).Operating System Concepts – 8th Edition 4.41 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.43 Silberschatz, Galvin and Gagne ©2009 User-Level Thread ULT: behavior (I) All of the work of thread management is done by the application and the By default, an application begins with a single thread and begins running the thread kernel is not aware of the existence of threads This application and its thread are allocated to a single process managed by the An application can be programmed to be multithreading by using a threads kernel library, which is a package of routines for thread management At any time that the application is running (i.e., the process is in the Running state), the application may spawn a new thread to run within the same process. Spawning is Threads library contains code for: done by invoking the spawn utility in the threads library. Control is passed to that creating and destroyng threads utility by a procedure call passing data between threads The threads library creates a data structure for the new thread and then passes control to one of the threads, within this process, in the Ready state using some scheduling thread execution scheduling algorithm saving and restoring thread context. When control is passed to the library, the context of the current thread is saved, and when the control is passed from the library to a thread the context of that thread is restored. The context consists of the contents of user registers, the program counter and the stack pointers. All the previous activities takes place in the user space and within a single process. The kernel is anaware of this activity.Operating System Concepts – 8th Edition 4.42 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.44 Silberschatz, Galvin and Gagne ©2009
  • 12. ULT: behavior (II) User-level threads: comments The kernel continues to schedule the process as a unit and assigns a single + Fast to create and switch execution state (Running, Blocked, Ready, etc.) to that process procedures that saves the threads state and the scheduler are user When a thread does something that may cause it to become blocked locally procedures (e.g., waiting for another thread in its process to complete some work), it no system call is needed calls a procedure in the threads library no context switch is needed This procedure checks if the thread must be put into blocked state. If so, it the memory cache does need to be flushed saves its context, calls the thread scheduler to pick another thread to run - When a ULT executes a system call, all the threads within the process are The thread scheduler looks in the thread table for a ready thread to run and blocked restores its context E.g., read from file can block all threads - User-level scheduler can fight with kernel-level scheduler - A multithread application cannot take advantage of multiprocessing. A kernel assigns one process to only one processor at a time. There are applcations that would benefit the ability to execute portions of code simultaneously.Operating System Concepts – 8th Edition 4.45 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.47 Silberschatz, Galvin and Gagne ©2009 User-level Threads Scheduling Exercise When a user level thread does I/O it blocks the entire process. 1. True 2. FalseOperating System Concepts – 8th Edition 4.46 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.48 Silberschatz, Galvin and Gagne ©2009
  • 13. Kernel-Level Threads Kernel-level Threads Scheduling The kernel knows the threads and manges them There is no thread table in each process. Instead, the kernel has a thread table that keeps track of all the threads in the system When a process wants to create a new thread or destroy an existing thread, it makes a kernel call, which then does the creation or destruction by updating the kernel thread table. The thread table containing TCBs holds the same information as with the ULT, but now kept in the kernel instead of in user space.Operating System Concepts – 8th Edition 4.49 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.51 Silberschatz, Galvin and Gagne ©2009 Kernel-Level Threads Kernel-level threads: comments Kernel-level threads + Kernel-level threads do not block process for system call if one thread in a process is blocked by a system call (e.g., for a page fault), the kernel can easily check if the process has one thread ready to run + Only one scheduler (and kernel has global view) - Can be difficult to make efficient (create & switch)Operating System Concepts – 8th Edition 4.50 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.52 Silberschatz, Galvin and Gagne ©2009
  • 14. Multithreading Models Many-to-One Model Many-to-One One-to-One Many-to-ManyOperating System Concepts – 8th Edition 4.53 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.55 Silberschatz, Galvin and Gagne ©2009 Many-to-One (ULT) One-to-One (KLT) Many user-level threads mapped to single kernel thread Each user-level thread maps to kernel thread the kernel has no knowledge of the application threads Examples Examples: Windows NT/XP/2000 Solaris Green Threads Linux GNU Portable Threads Solaris 9 and laterOperating System Concepts – 8th Edition 4.54 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.56 Silberschatz, Galvin and Gagne ©2009
  • 15. One-to-one Model Many-to-Many ModelOperating System Concepts – 8th Edition 4.57 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.59 Silberschatz, Galvin and Gagne ©2009 Many-to-Many Model Two-level Model Similar to M:M, except that it allows a user thread to be Allows many user level threads to be mapped to many kernel bound to kernel thread threads Examples Allows the operating system to create a sufficient number of kernel threads IRIX The threads library is responsible for scheduling user threads HP-UX on the available schedulable entities Tru64 UNIX When a thread performs a blocking system call, the kernel can Solaris 8 and earlier schedule another thread for execution Examples: Solaris prior to version 9 Windows NT/2000 with the ThreadFiber packageOperating System Concepts – 8th Edition 4.58 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.60 Silberschatz, Galvin and Gagne ©2009
  • 16. Two-level Model pthread_create() Synthax: pthread_create(thread,attr,start_routine,arg) Arguments: thread: A unique identifier for the new thread returned by the subroutine. attr: it specifies 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.Operating System Concepts – 8th Edition 4.61 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.63 Silberschatz, Galvin and Gagne ©2009 Pthreads #include <stdio.h> May be provided either as user-level or kernel-level #include <pthread.h> A POSIX standard (IEEE 1003.1c) API to: main() { create and destroy threads pthread_t f2_thread, f1_thread, f3_thread; int i1=1,i2=2; void *f2(), *f1(),*f3(); synchronize threads and lock program resourses pthread_create(&f1_thread,NULL,f1,&i1); manage thread scheduling pthread_create(&f2_thread,NULL,f2,&i2); API specifies behavior of the thread library, implementation is up to pthread_create(&f3_thread,NULL,f3,NULL); development of the library … Common in UNIX operating systems (Solaris, Linux, Mac OS X). } void *f1(int *i){ … } void *f2(int *i){ … } void *f3() { }Operating System Concepts – 8th Edition 4.62 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.64 Silberschatz, Galvin and Gagne ©2009
  • 17. pthread_exit() Example In main: creating thread 0 In main: creating thread 1 void *PrintHello(void *threadid) Hello World! Its me, thread #0! { When a thread has finished its work, it can exit by calling the In main: creating thread 2 long tid; pthread_exit() library procedure Hello World! Its me, thread #1! tid = (long) threadid; Hello World! Its me, thread #2! The thread then vanishes and is no longer schedulable and the stack is printf("Hello World! Its me, thread #%ld!n", tid); In main: creating thread 3 released. pthread_exit(NULL); In main: creating thread 4 } int main(int argc, char *argv[]) Hello World! Its me, thread #3! { Hello World! Its me, thread #4! pthread_t threads[NUM_THREADS]; int rc; long t; for(t=0;t<NUM_THREADS;t++){ printf("In main: creating thread %ldn", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc){ printf("ERROR; return code from pthread_create() is %dn", rc); exit(-1); } } pthread_exit(NULL); Silberschatz, Galvin and Gagne ©2009 } Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition 4.65 Operating System Concepts – 8th Edition 4.67 Example Multiple arguments via a structure: example void *PrintHello(void *threadid) include <pthread.h> { long tid; #include <stdio.h> tid = (long) threadid; #include <stdlib.h> printf("Hello World! Its me, thread #%ld!n", tid); #define NUM_THREADS 5 pthread_exit(NULL); } char *messages[NUM_THREADS]; int main(int argc, char *argv[]) { struct thread_data pthread_t threads[NUM_THREADS]; int rc; { long t; int thread_id; for(t=0;t<NUM_THREADS;t++){ int sum; printf("In main: creating thread %ldn", t); char *message; rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); }; if (rc){ printf("ERROR; return code from pthread_create() is %dn", rc); exit(-1); struct thread_data thread_data_array[NUM_THREADS]; } } pthread_exit(NULL); } Silberschatz, Galvin and Gagne ©2009 Silberschatz, Galvin and Gagne ©2009Operating System Concepts – 8th Edition 4.66 Operating System Concepts – 8th Edition 4.68
  • 18. pthread_join() void *PrintHello(void *threadarg) In some thread systems, one thread can wait for a (specific) thread to exit { by calling the pthread_join() procedure int taskid, sum; This procedure blocks the calling thread until (a specific) thread has exited char *hello_msg; The thread identifier of the thread to wait for is given as a parameter. struct thread_data *my_data; sleep(1); my_data = (struct thread_data *) threadarg; taskid = my_data->thread_id; sum = my_data->sum; hello_msg = my_data->message; printf("Thread %d: %s Sum=%dn", taskid, hello_msg, sum); pthread_exit(NULL); }Operating System Concepts – 8th Edition 4.69 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.71 Silberschatz, Galvin and Gagne ©2009 Joinable or not? int main(int argc, char *argv[]) { pthread_t threads[NUM_THREADS]; When a thread is created, one of its attributes defines whether it is joinable or int *taskids[NUM_THREADS]; detached. int rc, t, sum =0; Only threads that are created as joinable can be joined. messages[0] = "English: Hello World!"; If a thread is created as detached, it can never be joined. messages[1] = "French: Bonjour, le monde!"; messages[2] = "Spanish: Hola al mundo"; messages[3] = "German: Guten Tag, Welt!"; Define and initialize attribute object: messages[4] = "Russian: Zdravstvytye, mir!"; pthread_attr_t attr; for(t=0;t<NUM_THREADS;t++) { sum = sum + t; thread_data_array[t].thread_id = t; To explicitly create a thread as joinable, the attr argument in the thread_data_array[t].sum = sum; pthread_create() routine is used: thread_data_array[t].message = messages[t]; printf("Creating thread %dn", t); Initialize the attribute variable with pthread_attr_init() rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &thread_data_array[t]); To set the detach state: if (rc) { printf("ERROR; return code from pthread_create() is %dn", rc); pthread_attr_setdetachstate(&attr, THREAD_CREATE_DETACHED ); exit(-1); } } pthread_exit(NULL); }Operating System Concepts – 8th Edition 4.70 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.72 Silberschatz, Galvin and Gagne ©2009
  • 19. Example pthread_yield() pthread_yield() is another library call that allows a thread to voluntarily give up the CPU to let another thread run void *howdy(void *vargp); Thread attributes There is no such call for processes because the assumption is that (usually NULL) processes are competitive and each one wants all the CPU time it can get. int main() { pthread_t tid; However, since the threads of a process are working together and their code is written by the same programmer, it is possible that a thread Thread arguments pthread_create(&tid, NULL, howdy, NULL); (void *p) activates another thread. pthread_join(tid, NULL); exit(0); } /* thread routine */ void *howdy(void *vargp) { return value printf("Hello, world!n"); (void **p) return NULL; } Operating System Concepts – 8th Edition 4.73 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.75 Silberschatz, Galvin and Gagne ©2009 Execution Example A pthread program illustrating how to create a simple thread and some of main thread the pthread API call Pthread_create() The program implements the summation function where the summation Pthread_create() returns peer thread operation is run as a separate thread. call Pthread_join() printf() main thread waits for return NULL;peer thread to terminate (peer thread terminates) Pthread_join() returns exit() terminates main thread and any peer threads Operating System Concepts – 8th Edition 4.74 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.76 Silberschatz, Galvin and Gagne ©2009
  • 20. Example of Threads Accessing Another Thread’s Stack #include <pthread.h> #include <stdio.h> int sum; /* this data is shared by the thread(s) */ char **ptr; /* global */ /* thread routine */ void *runner(void *param); /* the thread */ void *thread(void *vargp) int main(int argc, char *argv[]) int main() { { { int myid = (int)vargp; pthread_t tid; /* the thread identifier */ int i; static int svar = 0; pthread_attr_t attr; /* set of attributes for the thread */ pthread_t tid; if (argc != 2) { fprintf(stderr,"usage: a.out <integer value>n"); char *msgs[N] = { printf("[%d]: %s (svar=%d)n", return -1; } "Messagge 1", myid, ptr[myid], ++svar); "Messagge 2" } if (atoi(argv[1]) < 0) { fprintf(stderr,"Argument %d must be non-negativen",atoi(argv[1])); }; return -1;} ptr = msgs; /* get the default attributes */ for (i = 0; i < 2; i++) Peer threads access main thread’s stack pthread_attr_init(&attr); Pthread_create(&tid, indirectly through global ptr variable NULL, /* create the thread */ thread, pthread_create(&tid,&attr,runner,argv[1]); (void *)i); Pthread_exit(NULL); /* now wait for the thread to exit */ pthread_join(tid,NULL); } printf("sum = %dn",sum); }Operating System Concepts – 8th Edition 4.77 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.79 Silberschatz, Galvin and Gagne ©2009 Mapping Vars to Mem. Instances Global var: 1 instance (ptr [data]) Local automatic vars: 1 instance (i.m, msgs.m ) /** * The thread will begin control in this function char **ptr; /* global */ Local automatic var: 2 instances ( */ myid.p0[peer thread 0’s stack], int main() myid.p1[peer thread 1’s stack] void *runner(void *param) { { ) int i; int i, upper = atoi(param); pthread_t tid; sum = 0; char *msgs[N] = { /* thread routine */ "Messagge 1", void *thread(void *vargp) if (upper > 0) { "Messagge 2" { for (i = 1; i <= upper; i++) }; int myid = (int)vargp; sum += i; ptr = msgs; static int svar = 0; } for (i = 0; i < 2; i++) Pthread_create(&tid, printf("[%d]: %s (svar=%d)n", pthread_exit(0); NULL, myid, ptr[myid], ++svar); } thread, } (void *)i); Pthread_exit(NULL); Local static var: 1 instance (svar [data]) }Operating System Concepts – 8th Edition 4.78 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.80 Silberschatz, Galvin and Gagne ©2009
  • 21. Shared Variable Analysis Thread Cancellation Which variables are shared? Terminating a thread before it has completed. This case is called target thread. Variable Referenced by Referenced by Referenced by The pthread_cancel(thread) function requests that thread be canceled instance main thread? peer thread 0? peer thread 1? Cancelability state determines whether a thread can receive a cancellation request. If the cancelability state is disabled, the thread does not receive any cancellation requests. The current threads cancelability state can be changed ptr yes yes yes by calling pthread_setcancelstate() svar no yes yes Two approaches (types) (the current threads cancelability type can be changed i.m yes no no by calling pthread_setcanceltype()): msgs.m yes yes yes Asynchronous cancellation terminates the target thread immediately. myid.p0 no yes no If you set a threads cancelability type to asynchronous, the thread can myid.p1 no no yes receive a cancellation request at any time. Deferred cancellation allows the target thread to periodically check if it should be cancelled Answer: A variable x is shared if multiple threads reference at least one If you set a threads cancelability type to deferred, cancellation requests are instance of x. Thus: acted on as soon as the thread reaches a cancellation point ptr, svar, and msgs are shared. pthread_testcancel() creates a cancellation point in the calling i and myid are NOT shared. thread.Operating System Concepts – 8th Edition 4.81 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.83 Silberschatz, Galvin and Gagne ©2009 Semantics of fork() and exec() Signal Does fork() duplicate only the calling thread or all threads? Signals are used in UNIX systems to notify a process that a some UNIX systems have chosen to have two versions of fork(): particular event has occurred one that duplicates all threads (forkall()) Examples: one that duplicates only the thread invoked by the fork() system call Typing certain key combinations at the terminal of a running (fork1()) process causes the system to send it certain signals: If exec() is called immediately after forking, then duplicating all threads CTRL-C sends an INT signal (SIGINT); by default, this causes is unnecessary. In this istance, duplicating only the calling thread is the process to terminate. appropriate. CTRL-Z sends a TSTP signal (SIGTSTP); by default, this causes the process to suspend execution. CTRL- sends a QUIT signal (SIGQUIT); by default, this causes the process to terminate and store the content of the memory (core dump).Operating System Concepts – 8th Edition 4.82 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8th Edition 4.84 Silberschatz, Galvin and Gagne ©2009