1 / 31

Thread 15213-S04, Recitation, Section A

This resource explores the thread memory model, system calls, pitfalls of using threads, semaphore final forms, and evaluation of pthread interfaces for web servers and browsers. Learn about the importance of concurrency, shared data, thread safety, and implementations. Dive into Posix Threads (Pthreads) interface for creating, terminating threads, managing thread IDs, synchronizing shared variables, and thread safety practices. The included "hello, world" program illustrates thread creation and termination. Understand the differences between joinable and detached threads, and how to protect shared variables in a concurrent system.

gborelli
Download Presentation

Thread 15213-S04, Recitation, Section A

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Thread15213-S04, Recitation, Section A Thread Memory Model Thread Interfaces (System Calls) Thread Safety (Pitfalls of Using Thread) Racing Semaphore Final & Evaluation Forms

  2. pthread_create • pthread_join • pthread_self • pthread_cancel • pthread_exit • pthread_mutex_init • pthread_mutex_[un]lock • pthread_cond_init • pthread_cond_[timed]wait

  3. Web Server Web Browser Web Server Proxy Web Browser Web Browser Web Server Why Do We Care About Thread • Useful for L7 Part II • A very important way to implement modern concurrent systems • What’s concurrency?

  4. Three Methods to Implement Concurrency • 1. Processes • Fork a child process for every incoming client connection • Difficult to share data among child processes • 2. Threads • Create a thread to handle every incoming client connection • Our focus today • 3. 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!

  5. View of Process • Process = process context + code, data, and stack Process context Code, data, and stack stack SP Program context: Data registers Condition code Stack pointer (SP) Program counter (PC) Kernel context: VM structures Descriptor table shared libraries run-time heap read/write data PC read-only code/data 0

  6. Thread memory model Thread 1 (main thread) Thread 2 (peer thread) stack 1 stack 2 Thread 1 context: Data registers Condition code SP1 PC1 Thread 2 context: Data registers Condition code SP2 PC2 View of Thread • Multiple threads can be associated with a process • Each thread has its own logical control flow (instruction flow) • Each thread has its own thread ID (TID) • Each thread shares the same code, data, and kernel context Shared code and data shared libraries run-time heap read/write data read-only code/data 0 Kernel context: VM structures Descriptor table

  7. Posix 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 • Synchronizing access to shared variables • pthread_mutex_init • pthread_mutex_[un]lock • pthread_cond_init • pthread_cond_[timed]wait

  8. The Pthread "hello, world" Program /* * hello.c - Pthreads "hello, world" program */ #include "csapp.h" /* thread routine */ void *thread(void *vargp) { printf("Hello, world!\n"); return NULL; } int main() { pthread_t tid; Pthread_create(&tid, NULL, thread, NULL); Pthread_join(tid, NULL); exit(0); }

  9. main thread Call Pthread_create() Pthread_create() returns peer thread return NULL; (peer thread terminates) Pthread_join() returns Execution of Threaded“hello, world” call Pthread_join() printf() main thread waits for peer thread to terminate exit() terminates main thread and any peer threads

  10. Practices • Basic usage of thread • Pthread_exit() & exit() • Joinable and detached thread • Thread safety • Protecting shared variable • Function that returns a static pointer • (more) ……

  11. pthread_exit() & exit() • Program 1.1 void *thread(void *vargp){ pthread_exit((void*)42);}int main(){ int i; pthread_t tid; pthread_create(&tid, NULL, thread, NULL); pthread_join(tid, (void **)&i); printf("%d\n",i);}

  12. pthread_exit() & exit() • Program 1.2 void *thread(void *vargp){ exit(42);}int main(){ int i; pthread_t tid; pthread_create(&tid, NULL, thread, NULL); pthread_join(tid, (void **)&i); printf("%d\n",i);}

  13. pthread_exit() & exit() • pthread_exit() only terminates the current thread, NOT the process • Exit() terminates all the threads in the process, i.e., the process itself

  14. Practices • Basic usage of thread • Pthread_exit() & exit() • Joinable and detached thread • Thread safety • Protecting shared variable • Function that returns a static pointer • (more) ……

  15. Joinable & 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.

  16. Practices • Basic usage of thread • Pthread_exit() & exit() • Joinable and detached thread • Thread safety • Protecting shared variable • Function that returns a static pointer • (more) ……

  17. Protecting shared variables • Program 1.5 int i = 42;void *thread(void *vargp){ printf("%d\n",i); }void *thread2(void *vargp){ i = 31; }int main(){ pthread_t tid, tid2; pthread_create(&tid2, NULL, thread2, (void*)&i); pthread_create(&tid, NULL, thread, (void*)&i); pthread_join(tid, (void**)&i); pthread_join(tid2, NULL);}

  18. Practices • Basic usage of thread • Pthread_exit() & exit() • Joinable and detached thread • Thread safety • Protecting shared variable • Function that returns a static pointer • (more) ……

  19. Functions that return a pointer to a static value int main () { struct in_addr a; a.s_addr = inet_addr(“1.1.1.1”); printf(“%s\n”, inet_ntoa(a)); } Output: 1.1.1.1 int main () { struct in_addr a, b; a.s_addr = inet_addr(“1.1.1.1”); b.s_addr = inet_addr(“2.2.2.2”); printf(“%s %s\n”, inet_ntoa(a), inet_ntoa(b)); } output: ???

  20. Thread Safety • Class 1: Functions that do not protect shared variables • Class 2: Functions that keep state across multiple invocations • rand() • Textbook P. 886 • Class 3: Functions that return a pointer to a static variable • Class 4: Functions that call thread-unsafe functions • May or may not be thread-unsafe • Textbook P.887

  21. More Practice Problems • Program 1.3 & 1.4 are left for your practice

  22. Racing • A race occurs when the correctness of a program depends on one thread reaching point x in its control flow before another thread reaches point y. • Generally related with the access to the shared variables • Need synchronization • Ways to do synchronization: • Semaphores • Mutual-exclusion

  23. Program 2.b void *foo(void *vargp) { int id; id = *((int *)vargp); printf("Thread %d\n", id);}int main() { pthread_t tid[2]; int i; for (i = 0; i < 2; i++) Pthread_create(&tid[i], NULL, foo, &i); Pthread_join(tid[0], NULL); Pthread_join(tid[1], NULL);} Racing!

  24. Program 2.a void *foo(void *vargp) { int myid; myid = *((int *)vargp); Free(vargp); printf("Thread %d\n", myid);}int main() { pthread_t tid[2]; int i, *ptr; for (i = 0; i < 2; i++) { ptr = Malloc(sizeof(int)); *ptr = i; Pthread_create(&tid[i], 0, foo, ptr); } Pthread_join(tid[0], 0); Pthread_join(tid[1], 0);} Good!

  25. Program 2.c void *foo(void *vargp) { int id; id = (int)vargp; printf("Thread %d\n", id);}int main() { pthread_t tid[2]; int i; for (i = 0; i < 2; i++) Pthread_create(&tid[i], 0, foo, i); Pthread_join(tid[0], 0); Pthread_join(tid[1], 0);} Good!

  26. The general solution for racing • Semaphore & mutual-exclusion • Mutex is a special case for the problems that semaphore targets to solve, and thus can be implemented using semaphore • But mutex seems to be more popularly used (probably because more people understand it) • Classic solution: Dijkstra's P and V operations on semaphores. • semaphore: non-negative integer synchronization variable. • P(s): [ while (s == 0) wait(); s--; ] • V(s): [ s++; ] • OS guarantees that operations between brackets [ ] are executed indivisibly. • Only one P or V operation at a time can modify s. • When while loop in P terminates, only that P can decrements. • Semaphore invariant: (s >= 0)

  27. Program 2.d sem_t s; /* semaphore s */void *foo(void *vargp) { int id; id = *((int *)vargp); V(&s); printf("Thread %d\n", id);}int main() { pthread_t tid[2]; int i; sem_init(&s, 0, 0); /* S=0 INITIALLY */ for (i = 0; i < 2; i++) { Pthread_create(&tid[i], 0, foo, &i); P(&s); } Pthread_join(tid[0], 0); Pthread_join(tid[1], 0);} Good!

  28. Program 2.e sem_t s; /* semaphore s */void *foo(void *vargp) { int id; P(&s); id = *((int *)vargp); V(&s); printf("Thread %d\n", id);}int main() { pthread_t tid[2]; int i; sem_init(&s, 0, 1); /* S=1 INITIALLY */ for (i = 0; i < 2; i++) { Pthread_create(&tid[i], 0, foo, &i); } Pthread_join(tid[0], 0); Pthread_join(tid[1], 0);} Racing!

  29. Summary So Far • Thread • Thread memory model • How to write thread programs • Thread safety (pitfalls of using thread) • Racing • Semaphore

  30. Final • Times • Exam Time: May 3rd (Monday) 5:30pm – 8:30p UC McConomy • Review Session: May 1st (Saturday), 3:00pm

  31. Evaluation Forms • There are questions on both sides • One student bring them to WH 5101

More Related