150 likes | 424 Views
Why Pthreads?. Pthread Interface. Pthread 為 POSIX 所定義的 thread 標準界面,它目前已經被移植到許多平台上,因此使用 pthread 會有較好的可移植性。 在 linux 中 pthread 是透過 clone 函式來產生 thread ,因此為 kernel space thread. 執行緒的建立與結束. Pthread create. #include <pthread.h> #include <stdio.h> #define NUM_THREADS 5
E N D
Pthread Interface • Pthread為POSIX所定義的thread標準界面,它目前已經被移植到許多平台上,因此使用pthread會有較好的可移植性。 • 在linux中pthread是透過clone函式來產生thread,因此為kernel space thread
Pthread create #include <pthread.h> #include <stdio.h> #define NUM_THREADS 5 void *PrintHello(void *threadid) { long tid; tid = (long)threadid; printf("Hello World! It's me, thread #%ld!\n", tid); pthread_exit(NULL); } int main (int argc, char *argv[]) { pthread_t threads[NUM_THREADS]; int rc; long t; for(t=0; t<NUM_THREADS; t++){ printf("In main: creating thread %ld\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } pthread_exit(NULL); }
Joinable or Not? • When a thread is created, one of its attributes defines whether it is joinable or detached. Only threads that are created as joinable can be joined. If a thread is created as detached, it can never be joined. • To explicitly create a thread as joinable or detached, the attr argument in the pthread_create() routine is used. The typical 4 step process is: • Declare a pthread attribute variable of the pthread_attr_t data type • Initialize the attribute variable with pthread_attr_init() • Set the attribute detached status with pthread_attr_setdetachstate() • When done, free library resources used by the attribute with pthread_attr_destroy()
Detaching: • The pthread_detach() routine can be used to explicitly detach a thread even though it was created as joinable. • There is no converse routine.
例 – thread.c int main() { pthread_t thread_id1, thread_id2; pthread_create(&thread_id1, NULL, &print_hello, NULL); pthread_create(&thread_id2, NULL, &print_world, NULL); while (1) { printf("-------------------------\n"); sleep(1); } return 0; } #include <pthread.h> #include <stdio.h> void *print_hello(void *argu) { while (1) { printf("Hello,\n"); sleep(1); } return NULL; } void *print_world(void *argu) { while (1) { printf("World!\n"); sleep(1); } return NULL; } • % gcc –o thread thread.c –lpthread • % ./thread
例 – thread2.c int main() { pthread_t thread_id1, thread_id2; char thread_argu1[256]; char thread_argu2[256]; strcpy(thread_argu1, "Hello"); strcpy(thread_argu2, "World"); pthread_create(&thread_id1, NULL, &print_hello, thread_argu1); pthread_create(&thread_id2, NULL, &print_world, thread_argu2); while (1) { printf("-------------------------\n"); sleep(1); } return 0; } #include <pthread.h> #include <stdio.h> #include <string.h> void *print_hello(void *argu) { while (1) { printf("%s,\n", (char *)argu); sleep(1); } return NULL; } void *print_world(void *argu) { while (1) { printf("%s!\n", (char *)argu); sleep(1); } return NULL; }
例 – detached.c int main() { pthread_attr_t attr; pthread_t thread_id1, thread_id2; /* Create detached threads. */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&thread_id1, &attr, &print_hello, NULL); pthread_create(&thread_id2, &attr, &print_world, NULL); return 0; } #include <pthread.h> #include <stdio.h> void *print_hello(void *argu) { while (1) { printf("Hello,\n"); sleep(1); } } void *print_world(void *argu) { while (1) { printf("World!\n"); sleep(1); } }
例 – join.c int main() { pthread_t thread_id1, thread_id2; char thread_argu1[256]; char thread_argu2[256]; strcpy(thread_argu1, "Hello"); strcpy(thread_argu2, "World"); pthread_create(&thread_id1, NULL, &print_hello, thread_argu1); pthread_create(&thread_id2, NULL, &print_world, thread_argu2); pthread_join(thread_id1, NULL); pthread_join(thread_id2, NULL); printf("--End of The Program.--\n"); return 0; } #include <pthread.h> #include <stdio.h> #include <string.h> void *print_hello(void *argu) { int i; for (i = 0; i < 5; i++) { printf("%s,\n", (char *)argu); sleep(1); } return NULL; } void *print_world(void *argu) { int i; for (i = 0; i < 5; i++) { printf("%s!\n", (char *)argu); sleep(1); } return NULL; }
Thread 範例 • “serial.c” in the Textbook
process vs. thread • A process = code + control (thread) • A thread in a process • Deadlock could happen • the "fork-one" model results in duplicating only the thread that called fork() • it is possible that at the time of the call another thread in the parent owns a lock. This thread is not duplicated in the child, so no thread will unlock this lock in the child. Deadlock occurs if the single thread in the child needs this lock. • The problem is more serious with locks in libraries