150 likes | 167 Views
CS 346 – Chapter 4. Threads How they differ from processes Definition, purpose Threads of the same process share: code, data, open files Types Support by kernel and programming language Issues such as signals User thread implementation: C and Java Commitment
E N D
CS 346 – Chapter 4 • Threads • How they differ from processes • Definition, purpose Threads of the same process share: code, data, open files • Types • Support by kernel and programming language • Issues such as signals • User thread implementation: C and Java • Commitment • For next day, please read chapter 4
Thread intro • Also called “lightweight process” • One process may have multiple threads of execution • Allows a process to do 2+ things concurrently • Games • Simulations • Even better: if you have 2+ CPU’s, you can execute in parallel • Multicore architecture demand for multithreaded applications for speedup • More efficient than using several concurrent processes
Threads • A process contains: • Code, data, open files, registers, memory usage (stack + heap), program counter • Threads of the same process share • Code, data, open files • What is unique to each thread? • Can you think of example of a computational algorithm where threads would be a great idea? • Splitting up the code • Splitting up the data • Any disadvantages?
2 types of threads • User threads • Can be managed / controlled by user • Need existing programming language API support: POSIX threads in C Java threads • Kernel threads • Management done by the kernel • Possible scenarios • OS doesn’t support threading • OS support threads, but only at kernel level – you have no direct control, except possibly by system call • User can create thread objects and manipulate them. These objects map to “real” kernel threads.
Multithreading models • Many-to-one: User can create several thread objects, but in reality the kernel only gives you one. Multithreading is an illusion • One-to-one: Each user thread maps to 1 real kernel thread. Great but costly to OS. There may be a hard limit to # of live threads. • Many-to-many: A happy compromise. We have multithreading, but the number of true threads may be less than # of thread objects we created. • A variant of this model “two-level” allows user to designate a thread as being bound to one kernel thread.
Thread issues • What should OS do if a thread calls fork( )? • Can duplicate just the calling thread • Can duplicate all threads in the process • exec ( ) is designed to replace entire current process • Cancellation • kill thread before it’s finished • “Asynchronous cancellation” = kill now. But it may be in the middle of an update, or it may have acquired resources. You may have noticed that Windows sometimes won’t let you delete a file because it thinks it’s still open. • “Deferred cancellation”. Thread periodically checks to see if it’s time to quit. Graceful exit.
Signals • Reminiscent of exception in Java • Occurs when OS needs to send message to a process • Some defined event generates a signal • OS delivers signal • Recipient must handle the signal. Kernel defines a default handler – e.g. kill the process. Or, user can write specific handler. • Types of signals • Synchronous: something in this program caused the event • Asynchronous: event was external to my program
Signals (2) • But what if process has multiple threads? Who gets the signal? For a given signal, choose among 4 possibilities: • Deliver signal to the 1 appropriate thread • Deliver signal to all threads • Have the signal indicate which threads to contact • Designate a thread to receive all signals • Rules of thumb… • Synchronous event just deliver to 1 thread • User hit ctrl-C kill all threads
Thread pool • Like a motor pool • When process starts, can create a set of threads that sit around and wait for work • Motivation • overhead in creating/destroying • We can set a bound for total number of threads, and avoid overloading system later • How many threads? • User can specify • Kernel can base on available resources (memory and # CPU’s) • Can dynamically change if necessary
POSIX threads • aka “Pthreads” • C language • Commonly seen in UNIX-style environments: • Mac OS, Linux, Solaris • POSIX is a set of standards for OS system calls • Thread support is just one aspect • POSIX provides an API for thread creation and synchronization • API specifies behavior of thread functionality, but not the low-level implementation
Pthread functions • pthread_attr_init • Initialize thread attributes, such as • Schedule priority • Stack size • State • pthread_create • Start new thread inside the process. • We specify what function to call when thread starts, along with the necessary parameter • The thread is due to terminate when its function returns • pthread_join • Allows us to wait for a child thread to finish
Example code #include <pthread.h> int sum; main() { pthread_t tid; pthread_attr attr; pthread_attr_init(&attr); pthread_create(&tid, &attr, fun, argv[1]); pthread join(tid, NULL); printf(“%d\n”, sum); } int fun(char *param) ... void *fun(void *param) { // compute a sum: // store in global // variable ... }
Java threads • Managed by the Java virtual machine • Two ways to create threads • Create a class that extends the Thread class • Put code inside public void run( ) • Implement the Runnable interface • public void run( ) • Parent thread (e.g. in main() …) • Create thread object – just binds name of thread • Call start( ) – creates actual running thread, goes to run( ) See book example
Skeletons class Worker extends Thread { public void run() { // do stuff } } public class Driver { // in main method: Worker w = new Worker(); w.start(); ... Continue/join } class Worker2 implements Runnable { public void run() { // do stuff } } Public class Driver2 { // in main method: Runnable w2=new Worker2(); Thread t = new Thread(w2); t.start(); // ...Continue/join }
Java thread states • This will probably sound familiar! • New • From here, go to “runnable” at call to start( ) • Runnable • Go to “blocked” if need I/O or going to sleep • Go to “dead” when we exit run( ) • Go to “waiting” if we call join( ) for child thread • Blocked • Go to “runnable” when I/O is serviced • Waiting • Dead