115213 Recitation Section C• Threads• Synchronization• Thread-safety of Library FunctionsShimin ChenDec. 2, 2002Outline215213 Recitation C Shimin ChenImportant Dates• Lab 7 Proxy: due on Thursday, Dec 5• Final Exam: Tuesday, Dec 17315213 Recitation C Shimin ChenConcurrent Servers• Iterative servers can only serve one client at a time• Concurrent servers are able to handle multiple requests in parallel• Required by L7 Part IIWebBrowserWebServerWebBrowserWebBrowserWebServerWebServerProxy415213 Recitation C Shimin ChenThree Ways for Creating Concurrent Servers1. Processes– Fork a child process for every incoming client connection– Difficult to share data among child processes2. Threads– Create a thread to handle every incoming client connection– Our focus today3. I/O multiplexing with Unix select()– Use select() to notice pending socket activity – Manually interleave the processing of multiple open connections– More complex! • ~ implementing your own app-specific thread package!2515213 Recitation C Shimin ChenTraditional View of a Process• Process = process context + code, data, and stackshared librariesrun-time heap0read/write dataProgram context:Data registersCondition codesStack pointer (SP)Program counter (PC)Kernel context:VM structuresDescriptor tablebrk pointerCode, data, and stackread-only code/datastackSPPCbrkProcess context615213 Recitation C Shimin ChenAlternate View of a Process• Process = thread + code, data, and kernel contextshared librariesrun-time heap0read/write dataThread context:Data registersCondition codesStack pointer (SP)Program counter (PC)Code and Dataread-only code/datastackSPPCbrkThread (main thread)Kernel context:VM structuresDescriptor tablebrk pointer715213 Recitation C Shimin ChenA Process With Multiple Threads• Multiple threads can be associated with a process– Each thread has its own logical control flow (instruction flow)– Each thread shares the same code, data, and kernel context– Each thread has its own thread ID (TID)shared librariesrun-time heap0read/write dataShared code and dataread-only code/dataThread 1 context:Data registersCondition codesSP1PC1stack 1Thread 1 (main thread)Kernel context:VM structuresDescriptor tablebrk pointerThread 2 context:Data registersCondition codesSP2PC2stack 2Thread 2 (peer thread)815213 Recitation C Shimin ChenThreads vs. Processes• How threads and processes are similar– Each has its own logical control flow.– Each can run concurrently.– Each is context switched.• How threads and processes are different– Threads share code and data, processes (typically) do not.– Threads are somewhat less expensive than processes.• Process control (creating and reaping) is twice as expensive as thread control. • Linux/Pentium III numbers:– ~20K cycles to create and reap a process.– ~10K cycles to create and reap a thread.3915213 Recitation C Shimin ChenPosix Threads (Pthreads) Interface• Standard interface for ~60 functions– Creating and reaping threads.• pthread_create• pthread_join– Determining your thread ID• pthread_self– Terminating threads• pthread_cancel• pthread_exit• exit [terminates all threads] , return [terminates current thread]– Synchronizing access to shared variables• pthread_mutex_init• pthread_mutex_[un]lock• pthread_cond_init• pthread_cond_[timed]wait1015213 Recitation C Shimin ChenThe Pthreads "hello, world" Program/* * hello.c - Pthreads "hello, world" program */#include "csapp.h"void *thread(void *vargp);int main() {pthread_t tid;Pthread_create(&tid, NULL, thread, NULL);Pthread_join(tid, NULL);exit(0);}/* thread routine */void *thread(void *vargp) {printf("Hello, world!\n"); return NULL;}Thread attributes (usually NULL)Thread arguments(void *p) return value(void **p)Upper case Pthread_xxxchecks errors 1115213 Recitation C Shimin ChenExecution of Threaded“hello, world”main threadmain thread waits for peer thread to terminateexit()terminates main thread and any peer threadspeer threadcall Pthread_create()call Pthread_join()Pthread_join() returnsprintf()return NULL;(peer threadterminates)Pthread_create() returns1215213 Recitation C Shimin ChenThread-Based Concurrent Echo Serverint main(int argc, char **argv){int listenfd, *connfdp, port, clientlen;struct sockaddr_in clientaddr;pthread_t tid;if (argc != 2) {fprintf(stderr, "usage: %s <port>\n", argv[0]);exit(0);}port = atoi(argv[1]);listenfd = open_listenfd(port);while (1) {clientlen = sizeof(clientaddr);connfdp = Malloc(sizeof(int));*connfdp = Accept(listenfd,(SA *)&clientaddr,&clientlen);Pthread_create(&tid, NULL, thread, connfdp);}}41315213 Recitation C Shimin ChenThread-Based Concurrent Server (cont)* thread routine */void *thread(void *vargp){int connfd = *((int *)vargp);Pthread_detach(pthread_self());Free(vargp);echo_r(connfd); /* thread-safe version of echo() */Close(connfd);return NULL;}?1415213 Recitation C Shimin ChenIssue 1: Detached Threads• At any point in time, a thread is either joinable or detached.• Joinable thread can be reaped and killed by other threads.– must be reaped (with pthread_join) to free memory resources.• Detached thread cannot be reaped or killed by other threads.– resources are automatically reaped on termination.• Default state is joinable.– use pthread_detach(pthread_self()) to make detached.• Why should we use detached threads?– pthread_join blocks the calling thread1515213 Recitation C Shimin ChenIssue 2: Avoid Unintended Sharing• For example, what happens if we pass the address of connfd to the thread routine as in the following code?connfdp = Malloc(sizeof(int));*connfdp = Accept(listenfd,(SA *)&clientaddr,&clientlen);Pthread_create(&tid, NULL, thread, connfdp); connfd = Accept(listenfd,(SA *)&clientaddr,&clientlen);Pthread_create(&tid, NULL, thread, (void *)&connfd); 1615213 Recitation C Shimin ChenIssue 3: Thread-safe• Easy to share data structures between threads• But we need to do this correctly!• Recall the shell lab:– Job data structures– Shared between main process and signal handler• Need ways to synchronize multiple control of flows51715213 Recitation C Shimin ChenThreads Memory Model• Conceptual model:– Each thread runs in the context of a process.– Each thread has its own separate thread context.• Thread ID, stack, stack pointer, program counter, condition codes, and general purpose registers.– All threads share the remaining process context.• Code, data, heap, and
View Full Document