Chapter: Threads: Ques/ons • How is a thread different from a process? • Why are threads useful? Operating Systems • How can POSIX threads be useful? – (Portable Opera/ng System Interface) API – enabling portability Threads between UNIX(es) and other opera/ng systems. • What are user-level and kernel-level threads? • What are problems with threads? Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Review : What Makes up a Process? Review : What is a Process? A process is a program in execution … • Program code (text) User Mode Address A thread have Space • Data heap (1) an execu/on stream and – global variables (2) a context • Execu/on stream – heap (dynamically allocated memory) – stream of instruc/ons routine1 var1 • Process stack – sequen/al sequence of instruc/ons var2 stack – “thread” of control – func/on parameters • Process ‘context’ (seen picture of this already) Running on a text main routine1 thread – return addresses – Everything needed to run (restart) the process … routine2 – Registers – local variables and func/ons code data files data arrayA • program counter, stack pointer, general purpose… arrayB registers stack • OS Resources – Address space • Everything the process can access in memory • Registers • Heap, stack, code address space are the shared resources – program counter, stack pointer of a(ll) thread(s) in a program Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA
Issues with Processes()? Processes versus Threads Thread (s): • How do processes ( independent memory • An execu/on stream that shares an address space – Overcome data flow over a file descriptor space) communicate ? main() – Overcome se_ng up `/ghter memory’ space { – Not really that simple (seen it, tried it – and you have i = 55; • Mul/ple threads within a single process fork(); too): // what is i Examples: • Message passing (send and receive) • Two processes (copies of each other) examining memory address • Shared Memory: Set up a shared memory area (easier)? 0xffe84264 see different values (i.e., different contents) • Problems: – same frame of reference • Two threads examining memory address 0xffe84264 see same – Overhead: Both methods add some kernel overhead value (i.e., same contents) lowering (poten/al) performance • Examples: – Complicated: IPC is not really that “natural” main() • ctest/i-process.c { • ctest/i-threading.c, i = 55; • increases the complexity of your code fork(); // what is i thread: shares i same memory storage Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA What Makes up a Thread? #include <stdio.h> // # printf #include <unistd.h> // # fork #include <stdlib.h> // # exit pid_t childpid = -1; int i; User Mode int main( int argc, char *argv[] ) Address ● Own stack (Is it necessary?) { Space Program Counter int i = -55; ● Own registers (Is it heap if( (childpid = fork()) == 0 ) necessary?) Stack Pointer { fflush(stdout); » Own program counter printf("[1. child (%10d)]: i = %3d address = %p\n", childpid, i, (void*) &i ); » Own stack pointer sleep(1); routine1 routine1 i = 11; var1 var1 ● State (running, sleeping) printf("[2. child (%10d)]: i = %3d address = %p\n", childpid, i, (void*) &i ); var2 var2 stack exit(0); ● Signal mask } else text main { routine1 // try to make sure parent is executed after child 'changes' i. routine2 sleep(10); printf("[b. parent (%10d)]: i = %3d address = %p\n", childpid, i, (void *) &i ); data arrayA } arrayB wait( (int *) 0 ); printf("[w. parent (%10d)]: i = %3d address = %p\n", childpid, i, (void *) &i ); } address space are the shared resources of a(ll) thread(s) in a program Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA
Single and Mul/threaded Process Why Support Threads? • Divide large task across several coopera6ve threads • Mul/-threaded task has many performance benefits code data files code data files ● Examples: registers stack registers registers registers » Web Server: create threads to: stack – Get network message from client stack stack – Get URL data from disk – Compose response – Send a response » Word processor: create threads to: – Display graphics – Read keystrokes from users – Perform spelling and grammar checking in background Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Why Threads instead of a Processes? Why Support Threads? • Advantages of Threads: • Divide large task across several coopera/ve threads • Mul6-threaded task has many performance benefits – Thread opera/ons cheaper than corresponding process opera/ons ● Adapt to slow devices • In terms of: Crea/on, termina/on, (context) switching » One thread waits for device while other threads computes – IPC cheap through shared memory ● Defer work • No need to invoke kernel to communicate between threads » One thread performs non-critical work in the background, • Disadvantages of Threads: when idle ● Parallelism – True Concurrent programming is a challenge (what does this mean? True concurrency?) » Each thread runs simultaneously on a multiprocessor – Synchroniza/on between threads needed to use shared variables (more on this later – this is HARD). – Parallelism vs. Concurrency Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA
Why are Threads Challenging? Why are Threads Challenging? pthread1 Example: Output? • Example: Transfer $50.00 between two main() gcc pthread1.c -o pthread1 -lpthread { accounts and output the total balance of the pthread_t t1, t2; accounts: char *msg1 = “Thread 1”; char *msg2 = “Thread 2”; int ret1, ret2; ret1 = pthread_create( &t1, NULL, print_fn, (void *)msg1 ); M = Balance in Maria’s account (begin $100 ) ret2 = pthread_create( &t2, NULL, print_fn, (void *)msg2 ); if( ret1 || ret2 ) T = Balance in Tucker’s account (begin $50 ) { fprintf(stderr, “ERROR: pthread_created failed.\n”); B = Total balance exit(1); } • Tasks: pthread_join( t1, NULL ); Idea: on distributing T = 50, M = 100 pthread_join( t2, NULL ); the tasks: printf( “Thread 1 and thread 2 complete.\n” ); (1) One thread debits M = M - $50.00 } and credits (2) The other Totals void print_fn(void *ptr) T = T + $50.00 Does that work? { printf(“%s\n”, (char *)ptr); B = M + T } Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Why are Threads Challenging? Common Programming Models • Tasks: T = 50, M = 100 • Manager/worker M = M - $50.00 One thread debits – Single manager handles input and assigns work to & credits the worker threads T = T + $50.00 • Producer/consumer B = M + T One thread totals – Mul/ple producer threads create data (or work) that is handled by one of the mul/ple consumer M = M - $50.00 M = M - $50.00 B = M + T threads T = T + $50.00 B = M + T M = M - $50.00 • Pipeline B = M + T T = T + $50.00 T = T + $50.00 – Task is divided into series of subtasks, each of which is handled in series by a different thread B = $150 B = $100 B = $150 Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA
Thread Support Latencies • Comparing user-level threads, kernel threads, and • Three approaches to provide thread processes support • Thread/Process Crea/on Cost: Null fork – Evaluate –with Null fork: the /me to create, schedule, execute, and complete – User-level threads the en/ty that invokes the null procedure • Thread/Process Synchroniza/on Cost: Signal-wait – Kernel-level threads – Evaluate – with Signal-Wait: the /me for an en/ty to signal a wai/ng en/ty and then wait on a condi/on ( overhead of synchroniza5on ) – Hybrid of User-level and Kernel-level threads Procedure call = 7 us User Level Kernel Level Kernel Trap = 17 us Processes Threads Threads Null fork 34 948 11,300 Signal-wait 37 441 1,840 30X,12X Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA User-Level Threads Blocked UL Threads: Jacke/ng • Avoids ‘blocking’ on system calls that block (e.g., I/O) • Many-to-one thread mapping • Solu/on: – Implemented by user-level run/me libraries – Instead of calling a blocking system call call an applica/on level I/O jacket • Create, schedule, synchronize threads at user- rou/ne (a nonblocking call) level, state in user level space – Jacket rou/ne provides code that determines whether I/O device is busy or – OS is not aware of user-level threads available (idle). • OS thinks each process contains only a single – Busy: thread of control P P • Thread enters the ready state and passes control to another thread • Control returns to thread it retries – Idle: ● Advantages • Thread is allowed to make system call. » Does not require OS support; Portable » Can tune scheduling policy to meet application (user level) demands » Lower overhead thread operations since no system calls ● Disadvantages » Cannot leverage multiprocessors (no true parallelism) » Entire process blocks when one thread blocks Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA Maria Hybinette, UGA
Recommend
More recommend