回到第一頁 What are threads n Threads are often called "lightweight processes” n In the UNIX environment a thread: u 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
回到第一頁 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 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 there is a thread system that you can use. It is called ``Solaris threads.'' n There is another thread system called ``Posix threads'' that is a standard. n 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 "Joining" is one way to accomplish synchronization between threads. Two other ways, mutexes and condition variables will be discussed later. n The pthread_join() subroutine blocks the calling thread until the specified threadid thread terminates. n 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 void *printme() { printf("Hello world\n"); 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 main.o –lpthread or cc –o main –lpthread main.c
回到第一頁 program 2 #include void *printme(void *ip) { int *i; i = (int *) ip; printf("Hi. I'm thread %d\n", *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 %d\n", i); pthread_join(tids[i], &retval); printf("Joined with tid %d\n", i); }
回到第一頁 example 3 #include 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_count1 = 0; res = pthread_create(&a_thread, NULL, thread_function, (void *)message); if (res != 0) { perror("Thread creation failed"); exit(EXIT_FAILURE); } while(print_count1++ < 20) { if (run_now == 1) { printf("1"); run_now = 2; } else { sleep(1); } }
回到第一頁 printf("\nWaiting 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=%d\n", count); exit(EXIT_SUCCESS); } void *thread_function(void *arg) { int print_count2 = 0; count++; printf("%s \n ", arg); while(print_count2++ < 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 integrity of a shared object that they access by allowing only one thread to access it at a time. n 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. n 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 For each shared object, all threads accessing that data must use the same mutex. n Each mutex must be initialized before use. n Define mutexes as global variables since they are generally required to be visible to all the threads that contend.
回到第一頁 #include #define NTHREADS 10 void *thread_function(); pthread_mutex_t mutex1 = 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: %d\n", counter); } void *thread_function() { int x = (int) pthread_self(); pthread_mutex_lock( &mutex1 ); printf("Thread number %ld\n", pthread_self()); printf("Thread %d: Now in critical region...\n", x); printf("Thread %d: Counter Value: %d\n", x, counter); printf("Thread %d: Incrementing Counter...\n", x); counter++; sleep(1); printf("Thread %d: New Counter Value: %d\n", x, counter); printf("Thread %d: Exiting critical region...\n", x); pthread_mutex_unlock( &mutex1 ); }