What are threads n n Threads are often

  • Slides: 12
Download presentation
What are threads n n Threads are often called "lightweight processes” In the UNIX

What are threads n n Threads are often called "lightweight processes” In the UNIX environment a thread: Exists within a process and uses the process resources u Has its own independent flow of control as long as its parent process exists and the OS supports it u May share the process resources with other threads that act equally independently (and dependently) u Dies if the parent process dies - or something similar u 回到第一頁

 All threads within a process share the same address space. Inter-thread communication is

All threads within a process share the same address space. Inter-thread communication is more efficient and in many cases, easier to use than inter-process communication. 回到第一頁

Advantage n Threaded applications offer potential performance gains and practical advantages over non-threaded applications

Advantage n Threaded applications offer potential performance gains and practical advantages over non-threaded applications in several other ways: u Overlapping CPU work with I/O: For example, a program may have sections where it is performing a long I/O operation. While one thread is waiting for an I/O system call to complete, CPU intensive work can be performed by other threads. u Priority/real-time scheduling: tasks which are more important can be scheduled to supersede or interrupt lower priority tasks. u Asynchronous event handling: tasks which service events of indeterminate frequency and duration can be interleaved. For example, a web server can both transfer data from previous requests and manage the arrival of new requests. 回到第一頁

Thread n n n there is a thread system that you can use. It

Thread n n n there is a thread system that you can use. It is called ``Solaris threads. '' There is another thread system called ``Posix threads'' that is a standard. int pthread_create(pthread_t *new_thread_ID, const pthread_attr_t *attr, void * (*start_func)(void *), void *arg); 回到第一頁

int pthread_join(pthread_t target_thread, void **status); n n n "Joining" is one way to accomplish

int pthread_join(pthread_t target_thread, void **status); n n n "Joining" is one way to accomplish synchronization between threads. Two other ways, mutexes and condition variables will be discussed later. The pthread_join() subroutine blocks the calling thread until the specified threadid thread terminates. The programmer is able to obtain the target thread's termination return status It is impossible to join a detached thread (discussed next) 回到第一頁

program 1 #include <pthread. h> #include <stdio. h> void *printme() { printf("Hello worldn"); return

program 1 #include <pthread. h> #include <stdio. h> void *printme() { printf("Hello worldn"); return NULL; } main() { pthread_t tcb; void *status; if (pthread_create(&tcb, NULL, printme, NULL) != 0) { perror("pthread_create"); exit(1); } if (pthread_join(tcb, &status) != 0) { perror("pthread_join"); exit(1); } } cc -c main. c cc -o main. o –lpthread or cc –o main –lpthread main. c 回到第一頁

program 2 #include <pthread. h> #include <stdio. h> void *printme(void *ip) { int *i;

program 2 #include <pthread. h> #include <stdio. h> void *printme(void *ip) { int *i; i = (int *) ip; printf("Hi. I'm thread %dn", *i); return NULL; } main() { int i, vals[4]; pthread_t tids[4]; void *retval; for (i = 0; i < 4; i++) { vals[i] = i; pthread_create(tids+i, NULL, printme, vals+i); } for (i = 0; i < 4; i++) { printf("Trying to join with tid %dn", i); pthread_join(tids[i], &retval); printf("Joined with tid %dn", i); } } 回到第一頁

#include <stdio. h> #include <unistd. h> #include <stdlib. h> #include <pthread. h> void *thread_function(void

#include <stdio. h> #include <unistd. h> #include <stdlib. h> #include <pthread. h> void *thread_function(void *arg); int run_now = 1; char message[] = "Hello World"; int count = 0; int main() { int res; pthread_t a_thread; void *thread_result; int print_count 1 = 0; res = pthread_create(&a_thread, NULL, thread_function, (void *)message); if (res != 0) { perror("Thread creation failed"); exit(EXIT_FAILURE); } while(print_count 1++ < 20) { if (run_now == 1) { printf("1"); run_now = 2; } else { sleep(1); 回到第一頁 } }

printf("n. Waiting for thread to finish. . . n"); res = pthread_join(a_thread, &thread_result); if

printf("n. Waiting for thread to finish. . . n"); res = pthread_join(a_thread, &thread_result); if (res != 0) { perror("Thread join failed"); exit(EXIT_FAILURE); } printf("Thread joined, the value of count=%dn", count); exit(EXIT_SUCCESS); } void *thread_function(void *arg) { int print_count 2 = 0; count++; printf("%s n ", arg); while(print_count 2++ < 20) { if (run_now == 2) { printf("2"); run_now = 1; } else { sleep(1); } } sleep(3); } 回到第一頁

Mutex: Mutual Exclusion n A mutex is used by multiple threads to ensure the

Mutex: Mutual Exclusion n A mutex is used by multiple threads to ensure the integrity of a shared object that they access by allowing only one thread to access it at a time. A mutex has two states, locked and unlocked. Each thread locks a mutex before it accesses the shared object and unlocks the mutex when it is finished accessing that object. If the mutex is locked by another thread, the thread requesting the lock waits for the mutex to be unlocked. 回到第一頁

Mutex: Mutual Exclusion (cond. ) n n n For each shared object, all threads

Mutex: Mutual Exclusion (cond. ) n n n For each shared object, all threads accessing that data must use the same mutex. Each mutex must be initialized before use. Define mutexes as global variables since they are generally required to be visible to all the threads that contend. 回到第一頁

#include <stdio. h> #include <pthread. h> #define NTHREADS 10 void *thread_function(); pthread_mutex_t mutex 1

#include <stdio. h> #include <pthread. h> #define NTHREADS 10 void *thread_function(); pthread_mutex_t mutex 1 = PTHREAD_MUTEX_INITIALIZER; int counter = 0; main() { pthread_t thread_id[NTHREADS]; int i, j; for(i=0; i < NTHREADS; i++) { pthread_create( &thread_id[i], NULL, &thread_function, NULL ); } for(j=0; j < NTHREADS; j++) { pthread_join( thread_id[j], NULL); } /* Now that all threads are complete I can print the final result. */ /* Without the join I could be printing a value before all the threads */ /* have been completed. */ printf("Final counter value: %dn", counter); } void *thread_function() { int x = (int) pthread_self(); pthread_mutex_lock( &mutex 1 ); printf("Thread number %ldn", pthread_self()); printf("Thread %d: Now in critical region. . . n", x); printf("Thread %d: Counter Value: %dn", x, counter); printf("Thread %d: Incrementing Counter. . . n", x); counter++; sleep(1); printf("Thread %d: New Counter Value: %dn", x, counter); printf("Thread %d: Exiting critical region. . . n", x); pthread_mutex_unlock( &mutex 1 ); 回到第一頁