1 / 31

Threads

Threads. By Dr. Yingwu Zhu. Review Multithreading Models. Many-to-one One-to-one Many-to-many. Many-to-one Model. Kernels do not support multiple threads of control Multithreading can be implemented entirely as a user-level library

cody-duffy
Download Presentation

Threads

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. Threads By Dr. Yingwu Zhu

  2. Review Multithreading Models • Many-to-one • One-to-one • Many-to-many

  3. Many-to-one Model • Kernels do not support multiple threads of control • Multithreading can be implemented entirely as a user-level library • Schedule multiple threads onto the process’s single kernel thread; multiplexing multiple user threads on a single kernel thread

  4. Many-to-one (cont.): Benefits • Cheap synchronization • When a user thread wishes to perform synchronization, the user-level thread lib. checks to see if the thread needs to block. • If a user thread does, the user-level thread lib. enqueues it, and dequeues another user thread from the lib.’s run queue, and swithes the active thread. • No system calls are required • Cheap thread creation • The thread lib. need only create a context (i.e., a stack and registers) and enqueues it in the user-level run queue

  5. Many-to-one (cont.): Benefits • Resource efficiency • Kernel memory is not wasted on a stack for each user thread • Allows as many thread as VM permits • Portability • User-level threads packages are implemented entirely with standard UNIX and POSIX lib. calls

  6. Many-to-one (cont.): Drawbacks • Single-threaded OS interface • If a user thread blocks (e.g, blocking system calls), the entire process blocks and so no other user thread can execute until the kernel thread (which is blocked in the system call) becomes available • Solution: using nonblocking system calls • Can not utilize MP achitectures • Examples: Java, Netscape

  7. One-to-one Model • Each user thread has a kernel thread

  8. One-to-one (cont.): Benefits • Scalable parallelism • Each kernel thread is a different kernel-schedulable entity; multiple threads can run concurrently on multiprocessors • Multithreaded OS interface • When one user thread and its kernel thread block, the other user threads can continue to execute since their kernel threads are unaffected

  9. One-to-one (cont.): Drawbacks • Expensive synchronization • Kernel threads require kernel involvement to be scheduled; kernel thread synchronization will require a system call if the lock is not immediately acquired • If a trap is required, synchronization will be from 3-10 times more costly than many-to-one model • Expensive creation • Every thread creation requires explicit kernel involvement and consumes kernel resources • 3-10 times more expensive than creating a user thread

  10. One-to-one (cont.): Drawbacks • Resource inefficiency • Every thread created by the user requires kernel memory for a stack, as well as some sort of kernel data structure to keep track of it • Many parts of many kernels cannot be paged out • The presence of kernel threads is likely to displace physical memory for applications

  11. Many-to-Many Model • Combing the previous two models • User threads are multiplexed on top of kernel threads which in turn are scheduled on top of processors • Taking advantage of the previous two models while minimizing both’s disadvantages • Creating a user thread does not necessarily require the creation of a kernel threads; synchronization can be purely user-level

  12. Pthread Tutorial • Creating and destroying threads • How to use POSIX threads

  13. How to compile? • $ gcc –o proj2 proj2.c –pthread • The option specifies that pthreads library should be linked • causes the complier to properly handle multiple threads in the code that it generates

  14. Creating and Destroying Threads • Creating threads • Step 1: create a thread • Step 2: send the thread one or more parameters • Destroy threads • Step 1: destroy a thread • Step 2: retrieve one or more values that are returned from the thread

  15. Creating Threads • #include <pthread.h> • int pthread_create (pthread_t *thread_id, pthread_attr_t *attr, void *(*thread_fun)(void *), void *args); • The #1 para returns thread ID • The #2 para pointing to thread attr. NULL represents using the default attr. settings • The #3 para as pointer to a function the thread is to execute • The #4 para is the arguments to the function

  16. Thread Terminates • Pthreads terminate when the function returns, or the thread calls pthread_exit() • int pthread_exit(void *status); • status is the return value of the thread • A thread_fun returns a void*, so calling “return (void *) is the equivalent of this function

  17. Thread termination • One thread can wait (or block) on the termination of another by using pthread_join() • You can collect the exit status of all threads you created by pthread_join() • int pthread_join(pthread_t thread_id, void **status) • The exit status is returned in status • pthread_t pthread_self(); • Get its own thread id • int pthread_equal(pthread_t t1, pthread_t t2); • Compare two thread ids

  18. Example #include <pthread.h> void *thread_fun(void *arg) { int *inarg = (int *)arg; … return NULL; } Int main() { pthread_t tid; void *exit_state; int val = 42; pthread_create(&tid, NULL, thread_fun, &value); pthread_join(tid, &exit_state); return 0; }

  19. Kill Threads • Kill a thread before it returns normally using pthread_cancel() • But • Make sure the thread has released any local resources; unlike processes, the OS will not clean up the resources • Why? Threads in a process share resources

  20. Exercise • Write a multithreaded program that calculates the summation of a non-negative integer in a separate thread • The non-negative integer is from command-line parameter • The summation result is kept in a global variable:int sum; // shared by threads

  21. Step 1: write a thread function void *thread_sum(void *arg) { int i; int m = (int)(*arg); sum = 0; //initialization for (i = 0; i <= sum; i++) sum += I; pthread_exit(0); }

  22. Step 2: write the main() int sum; int main(int argc, char *argv[]) { pthread_t tid; if (argc != 2) { printf(“Usage: %s <integer-para>\n”, argv[0]); return -1; } int i = atoi(argv[1]); if (i < 0) { printf(“integer para must be non-negative\n”); return -2; } pthread_create(&tid, NULL, thread_sum, &i); pthread_join(tid, NULL); printf(“sum = %d\n”, sum); }

  23. Exercise • Write a program that creates 10 threads. Have each thread execute thesame function and pass each thread a unique number. Each thread should print “Hello, World (thread n)” five times where ‘n’ is replaced by the thread’s number. Use an array of pthread t objects to hold the various thread IDs. Be sure the program doesn’t terminate until all the threadsare complete. Try running your program on more than one machine. Are there any differences in how it behaves?

  24. Returning Results from Threads • Thread function return a pointer to void: void * • Pitfalls in return value

  25. Pitfall #1 void *thread_function ( void *) { int code = DEFAULT_VALUE; return ( void *) code ; } Only work in machines where integers can convert to a point and then back to an integer without loss of information

  26. Pitfall #2 void *thread_function ( void *) { char buffer[64]; // fill up the buffer with sth good return ( void *) buffer; } This buffer will disappear as the thread function returns

  27. Pitfall #3 void *thread_function ( void *) { static char buffer[64]; // fill up the buffer with sth good return ( void *) buffer; } It does not work in the common case of multiple threads running the same thread funciton

  28. Right Way void *thread_function ( void *) { char* buffer = (char *)malloc(64); // fill up the buffer with sth good return ( void *) buffer; }

  29. Right Way int main() { void *exit_state; char *buffer; …. pthread_join(tid, &exit_state); buffer = (char *) exit_state; printf(“from thread %d: %s\n”, tid, buffer); free(exit_state); }

  30. Exercise • Write a program that computes the square roots of the integers from 0 to 99 in a separate thread and returns an array of doubles containing the results. In the meantime the main thread should display a short message to the user and then display the results of the computation when they are ready.

  31. Exercise • In textbook 4.7 and 4.9

More Related