1. Trang chủ
  2. » Công Nghệ Thông Tin

Tạo lập thread - bài tập thread docx

20 588 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 20
Dung lượng 241 KB

Nội dung

I.1 Tạo lập thread. I.1.1. Thiết lập Thuộc tính cho thread. 1) pthread_attr_init(&attr); 2) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 3) pthread_create(&threads[0], &attr, inc_count, (void*)&thread_ids[0]); Lệnh 1) tạo ra biến attr để nhớ thuộc tính, lệnh 2) nạp thuộc tính cho nó – ở đây thuộc tính được chỉ định là “PTHREAD_CREATE_JOINABLE”, lệnh 3) chỉ định thread có thuộc tính attr. Chúng ta thường sử dụng thuộc tính ngầm định NULL, chỉ thị này cho phép các thread “join” được với trình chính. I.1.2. Tạo lập, Giao nhiệm vụ & Truyền tham số cho thread. I.1.2.A Các bước cơ bản. Để tạo lập và điều kiển một thread ta cần phải thực hiện 5 bước cơ bản sau 1. Mô tả thread: void * proc_1(int x,y) 2. Đăng ký thread: pthread_t tid; 3. Khởi tạo (đăng ký thuộc tính), giao nhiệm vụ, và truyền dữ liệu. pthread_create(&tid, NULL, &proc_1, (void*)&arg); 4. Xác định thread pthread_equal(pthread_self(), ) 5. Thu hồi pthread_join(tid, NULL); “Mô tả thread” là việc tạo ra một trình con. Nó chính là thread sau này. Các lệnh còn lại chỉ là thủ tục để cho trình con này biến thành thread, tức là chạy song song và có các thuộc tính cần thiết. Các lệnh này gồm có 1) Lệnh khởi tạo và giao nhiệm vụ pthread_create Lệnh này kết nối một thread với một hàm con (được gọi tắt là thread 1 , hay hàm được kích hoạt thành thread). Lệnh còn đảm nhận trách nhiệm truyền dữ liệu cho thread. Dữ liệu phải được khai báo trước và để ở đâu đó trong bộ nhớ. Tuy nhiên không phải các dữ liệu này được truyền cho thread, mà chỉ là địa chỉ của những khối dữ liệu cần phải truyền, mà thôi. Các địa chỉ là các con trỏ – nó có thể là địa chỉ của một vùng nhớ, và cũng có thể là biến địa chỉ chứa địa chỉ của vùng nhớ có dữ liệu. Ví dụ, nếu cần truyền giá trị chứa trong biến X thì (do địa chỉ của X là &X) chỉ thị truyền là (void*)&X. Còn nếu địa chỉ của dữ liệu được để trong con trỏ P thì chỉ thị truyền là (void*)P. Do chỉ được truyền cho địa chỉ, cho nên, để có thể sử dụng được những dữ liệu này, thread phải tự định dạng các dữ liệu này sao cho hợp với dạng vốn có của chúng. 2) Lệnh kết thúc hoạt động pthread_join Lệnh này đóng vai trò đồng bộ thread với trình chính 2 . Số là, tiến trình chính, sau khi khởi tạo ra các thread, thì vẫn tiếp tục hoạt động – và các thread do nó tạo ra thì chạy song song với nó. Nếu trình chính mà muốn sử dụng một kết quả nào đó do thread tính ra, thì nó phải biết được thời điểm mà thread kết thúc hoạt động của mình. Trình chính không thể tự biết được thời điểm các thread kết thúc hoạt động, vì vậy cần phải có một lệnh – và đó chính là lệnh pthread_join – bắt trình chính (nếu nó đến lệnh này sớm hơn) phải chờ để thread kết thúc công việc của mình. Điều này hàm ý, ở lệnh tiếp theo sau lệnh nó, thread tương ứng đã không còn nữa 3 . Lệnh pthread_joint chỉ thị chờ cho từng thread một, và chính vì vậy trong chỉ thị lệnh phải có thông báo tên của thread cần “join” với trình chính – hay trình chính phải chờ. I.1.2.B Ví dụ về tạo lập & truyền dữ liệu cho thread. Ví dụ 1. Tạo lập thread. Trình chính (thread chính) tạo ra một thread để làm một việc gì đó cho mình. Trong ví dụ này thread in “Hello, ” còn trình chính in “World!”. Do thread chạy song song với trình chính mà các từ in ra không theo thứ tự nhất định, nó có thể là “Hello World” và cũng có thể là “World Hello”. #include <iostream.h> #include <pthread.h> void * print_hello(void *args) { cout<<"Hello, ";return NULL;} void *main() 1 Trên thực tế mỗi khi lệnh này được gọi thì có 2 thread được tạo ra. Thread “con” dùng để chạy trình con và thread “mẹ” để chạy trình chính. Như vậy thread và trình chính đều là các thread. Thread “con” có thể có được những tính chất như quyền ưu tiên, lịch hoạt động, thời điểm kết thúc hoạt động (đồng bộ hay không) 2 Thời điểm kết thúc hoạt động của một thread có thể là đồng bộ hay là không đồng bộ. Nếu một thread được khai báo là “kết hợp” (joined) thì nó chỉ thực sự kết thúc hoạt động (hủy bỏ hoàn toàn bộ nhớ do nó tạo ra như stack và header) khi lệnh trình chính gọi lệnh “pthread_join()”. Ngược lại nếu nó thuộc loại “tách rời” (detached) thì nó sẽ giải phóng tất cả bộ nhớ do nó tạo ra khi nó kết thúc hoạt động 3 Lưu ý lệnh này không hủy bỏ vùng bộ nhớ mà thread đã xin cấp. { pthread_t tid; pthread_create(&tid, NULL, &print_hello, NULL); cout<<"World! "; pthread_join(tid, NULL); return NULL; } Ví dụ 2. Truyền dữ liệu. Do đặc thù của tính song-song trong xử lý mà chúng ta cần phải tin chắc rằng khoảng thời gian kể từ lúc một thread được tạo ra cho đến lúc nó hoạt động là phải được khống chế và là phải là không đáng kể. Điều này hàm ý là tổng thời gian thực tế cần thiết để truyền dữ liệu cho nó phải là rất ít – diễn ra trong khoảng một vài lệnh asambly. Như vậy, giao nhiệm vụ cho thread cũng như cấp dữ liệu cho nó đều là thông qua con trỏ. Con trỏ sẽ trỏ tới địa chỉ, nơi lưu giữ trình con cần phải được kích hoạt để chạy song song; con trỏ sẽ trỏ tới vùng dữ liệu nơi lưu giữ dữ liệu cần cho thread. Tóm lại nguyên lý truyền dữ liệu cho một thread là “truyền con trỏ đến vùng dữ liệu”. Sau đây là ví dụ về việc truyền nói trên. Hàm được kích hoạt là “Say”. Đó là một hàm được khai báo ở dạng con trỏ, và chính con trỏ này sẽ được truyền cho thread để thông báo hàm cần phải được kích hoạt. Hàm này sẽ in ra màn hình lời chào bằng ở các ngôn ngữ khác nhau. Dữ liệu cần truyền cho thread để nó hoạt động là các dòng chữ và chúng ta không truyền hẳn cho các thread cả dòng chữ, bở dung lượng dữ liệu phải truyền sẽ rất nhiều vì các dòng này tương đối dài, mà chúng ta chỉ truyền cho nó địa chỉ nơi lưu giữ các lời chào đó. Trong ví dụ sau, trình chính tạo ra và truyền dữ liệu cho 3 thread chạy song song. Mỗi thread in ra một dòng thông báo trên màn hình. Các dòng chữ đó là các câu chào (đã để sẵn trong bộ nhớ, trong một mảng) ở các ngôn ngữ khác nhau: "English: Hello World!", "French: Bonjour, le monde!", "Vietnam: Chao tat ca". Để làm được việc này, mỗi thread nhận được địa chỉ ứng với vị trí dòng chữ tương ứng. #include <iostream.h> #include "pthread.h" #include <string> using namespace std; #define NUM 3 string mess[NUM]; void *Say(void *messages) { cout<< (char *) messages << "\n"; pthread_exit(NULL); return NULL; } void *main(int argc, char *argv[]) { pthread_t threads[NUM]; mess [0] = "English: Hello World!"; mess [1] = "French: Bonjour, le monde!"; mess [2] = "Vietnam: Chao tat ca!"; for(int t=0;t<NUM;t++) {pthread_create(&threads[t], NULL, &Say,(void *) mess[t].c_str());} for(t=0;t<NUM;t++) pthread_join(threads[t],NULL); return NULL; } Dữ liệu có thể được lưu dưới dạng mảng và truyền cho các thread chỉ số của mảng. Việc làm này thường dùng khi sử dụng mảng thread, nó cho phép chúng ta sử dụng vòng lặp “for” để tạo lập giao nhiệm vụ và truyền dữ liệu cho các thread. #include <stdio.h> #include <malloc.h> #include "pthread.h" #define NUM 3 char *messages[NUM]; void *PrintHello(void *threadid) { int *id_ptr, taskid; id_ptr = (int *) threadid; taskid = *id_ptr; printf("Thread %d: %s\n", taskid, messages[taskid]); pthread_exit(NULL); return NULL; } void main(int argc, char *argv[]) { pthread_t threads[NUM]; int *taskids[NUM]; int t; messages[0] = "English: Hello World!"; messages[1] = "French: Bonjour, le monde!"; messages[2] = "Vietnam: Chao tat ca!"; for(t=0;t<NUM;t++) { taskids[t] = (int *) malloc(sizeof(int)); *taskids[t] = t; pthread_create(&threads[t], NULL, PrintHello, (void *) taskids[t]); } for(t=0;t<NUM;t++) pthread_join(threads[t],NULL); } /*Result: Thread 0: English: Hello World! Thread 1: French: Bonjour, le monde! Thread 2: Vietnam: Chao tat ca! Press any key to continue */ Lưu ý rằng, việc truyền trực tiếp giá trị “t” sẽ dẫn đến sai lầm, bởi vì, vào thời điểm thread hoạt động thì (do vòng for làm nó tăng lên) giá trị “t” ấy, có thể, đã khác đi rồi! Như vậy khúc trình sau đây là sai. for(t=0;t<NUM;t++) { printf("Creating thread %d\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); } } Ví dụ 3. Truyền nhiều dữ liệu cho thread. Có thể truyền nhiều dữ liệu bằng cách liệt kê, và cũng có thể truyền con trỏ – trỏ tới tới một cấu trúc hay một Object. Ví dụ 4. Truyền dữ liệu cho thread thông qua việc truyền con trỏ tới một cấu trúc có chứa nhiều trường với định dạng khác nhau. #include <iostream.h> #include "pthread.h" #include <string> #define NUM 3 using namespace std; string mess[NUM]; struct wrapper { int id; string message; } data_array [NUM]; void * PrintHello(void* data) { cout<< ((wrapper*)data)->id << " > "; cout<< ((wrapper*)data)->message.c_str() << "\n"; return NULL; } void *main() { pthread_t threads[NUM]; for(int t=0;t<NUM;t++) { switch (t){ case 0: data_array[0].message="Thread 0"; case 1: data_array[1].message="Thread 1"; case 2: data_array[2].message="Thread 2"; } data_array[t].id = t; pthread_create(&threads[t], NULL, PrintHello, (void *) & data_array[t]); } for(t=0;t<NUM;t++){pthread_join(threads[t], NULL);} return NULL; } /*Result: 0 > Thread 0 1 > Thread 1 2 > Thread 2 */ Ví dụ 5. Các thread có thể là hàm của một class, nhưng hàm này phải thuộc loại được khai báo “static”. #include <iostream.h> #include "pthread.h" class Hello{ public: static void* print(void* msg); }; void* main() { pthread_t thread1, thread2; char *message1="Hello "; char *message2="World \n"; pthread_create(&thread1,NULL,Hello::print,(void *)message1); pthread_create(&thread2,NULL,Hello::print,(void *)message2); pthread_join(thread1, NULL); pthread_join(thread2, NULL); return NULL; } void * Hello::print(void* msg) { char *message; message= (char *)msg; cout<<message; return NULL; } /*Result: Hello World */ Ví dụ 6. Các thread có thể là hàm của một object, nhưng hàm này phải thuộc loại được khai báo “static”. #include <iostream.h> #include "pthread.h" class Hello{ public: static void* print(void* msg); }; void * main() { pthread_t thread1, thread2; Hello *H=new Hello; char *message1="Hello "; char *message2="World \n"; pthread_create(&thread1,NULL,H->print,(void *)message1); pthread_create(&thread2,NULL,H->print,(void *)message2); pthread_join(thread1, NULL); pthread_join(thread2, NULL); return NULL; } void * Hello::print(void* msg) { char *message; message= (char *)msg; cout <<message; return NULL; } /* Hello World */ Ví dụ 7. Thủ tục của một Object được kích hoạt thành thread. #include <iostream.h> #include "pthread.h" class ThreadClass; struct wrapper { ThreadClass* Me; int a; }; class ThreadClass {public: int a; static void* function(void* arg) { wrapper* Unpack = (wrapper*) arg; ThreadClass* Hidden= Unpack->Me; Hidden->a = Unpack->a; cout<<"I got: " << Hidden->a <<"\n"; return NULL; } }; int main() { pthread_t Thread1; int one = 1; ThreadClass Test; wrapper ToPass; ToPass.Me = &Test; ToPass.a = one; pthread_create(&Thread1, NULL, Test.function, &ToPass); pthread_join(Thread1, NULL); return 0; } /*Result: I got: 1 Press any key to continue */ Ví dụ 8. Sử dụng thủ tục “static” để gọi các thủ tục “non static”. #include <iostream.h> #include "pthread.h" class Hello{ public: void* print(void* msg); static void * test(void* arg); //the entry static function }; struct pack_data{ Hello * self; char * str_content; }; //the wrapper void *main() { pthread_t thread1, thread2; Hello *H= new Hello; struct pack_data *pk1 = new pack_data; pk1->self=H; pk1->str_content="Hello "; struct pack_data *pk2 = new pack_data; pk2->self=H; pk2->str_content="World \n"; pthread_create(&thread1,NULL,H->test,(void *)pk1); pthread_create(&thread2,NULL,H->test,(void *)pk2); pthread_join(thread1, NULL); pthread_join(thread2, NULL); return NULL; } void * Hello::print(void* msg) //non static function { char *message; message= ((pack_data *)msg)->str_content; cout<< message; return NULL; } void * Hello::test(void *arg) //static function { Hello *ptr= new Hello; ptr= ((pack_data *)arg)->self; ptr->print(arg); //call a static function return NULL; } /*Result: Hello World Press any key to continue */ I.1.2.C Tạo mảng thread Ví dụ 1. Trong ví dụ sau một mảng thread được tạo ra và được giao nhiệm vụ. Nhiệm vụ chỉ đơn thuần là mỗi thread chạy 4 lần, in ra màn hình số thứ tự của mình, rồi kết thúc nhiệm. #include <stdlib.h> #include <malloc.h> #include <stdio.h> #include "pthread.h" void *do_one_thing(void *pnum) { int i; for (i = 0; i < 4; i++) { printf("%d is doing a thing\n", (int *)pnum); }return NULL;} void main() { int i, n=5; pthread_t *thread1; int* Nthread; thread1 = (pthread_t *) calloc(n, sizeof(pthread_t)); Nthread = (int *) calloc(n, sizeof(int)); for(i=0;i<n;i++){ Nthread[i]=i; pthread_create(&(thread1[i]), NULL, &do_one_thing, (void*)Nthread[i]); } for(i=0;i<n;i++){pthread_join(thread1[i], NULL);} free(Nthread); free(thread1); return; } Ví dụ 2. Trong ví dụ này mảng 10 Object, đánh số từ 0 9, thuộc Class “ThreadClass” được tạo ra. Trong mỗi Object có một hàm được kích hoạt thành thread – khi chạy nó sẽ in ra màn hình số hiệu của Object. Có thể quan niệm 10 Object này tồn tại và vận hành độc lâp. Lệnh pthread_join chỉ kết thúc hoạt động của các hàm, trong khi 10 Object này vẫn tồn tại. #include <iostream.h> #include "pthread.h" class ThreadClass {public: int a; static void* function(void* arg) { cout<<" I am Object: " << (int)((ThreadClass *) arg)->a <<"\n";return NULL;} }; int main() { int i; pthread_t Thread[10]; ThreadClass Test[10]; for (i=0; i<10;i++){Test[i].a=i;} for (i=0; i<10;i++){ pthread_create(&Thread[i], NULL, Test[i].function, &Test[i]); } for (i=0; i<10;i++) pthread_join(Thread[i], NULL); return 0; } I.1.3. Sự khác nhau giữa thread và trình con. I.1.3.A Thread là trình con được kích hoạt để chạy song song. Trong ví dụ sau hai thread là các trình con first_function(), và second_function() nhưng được kích hoạt để chạy song song. pthread_create(&thread1, NULL, &first_function, &i); pthread_create(&thread2, NULL, &second_function, &j); Để thấy được dấu hiệu chạy song song của hai thread này, chúng ta ra lệnh cho mỗi thread liên tiếp in ra 10 lần thông báo về mình. Khi chạy khúc trình sau chúng ta sẽ sớm nhận ra các thông báo hiện ra trên màn hình đan xen kẽ vào nhau, chứng tỏ chúng hoạt động thật sự song song. Trong ví dụ này final_function() là trình con bình thường và chỉ khi nào gọi tới nó mới chạy. Các thread được khởi tạo, và mỗi thread làm một việc. Khi kết thúc công việc, pthread_join(thread1, NULL); pthread_join(thread2, NULL); kết quả tính toán của 2 thread được trình con gom lại. Khi trình con gom kết quả thì các thread đã không còn tồn tại, tuy vậy kết quả của nó được để ở trong 2 ô nhớ “i” và “j” đã tạo sẵn ngay trong trình chính. Trình final_function() sẽ dùng các kết quả này. 1. #include <stdio.h> 2. #include "pthread.h" 3. int i=0, j=0; 4. void * first_function(void *num) 5. { int x,y,z=0; 6. int * a =(int*)num; 7. for(x=0; x< 10; x++) 8. { printf("Inside the first_function %d\n",*a); 9. for (y=0; y< 1000; y++) z =z+1; 10. (*a)++; 11. } 12. num=a; 13. return NULL; 14. } 15. void * second_function(void *num) 16. { int x,y,z=0; 17. int * a =(int*)num; 18. for(x=0; x< 20; x++) 19. { printf("Inside the second_function %d\n",*a); 20. for (y=0; y< 1000; y++) z =z+1; 21. (*a)++; 22. } 23. num=a; 24. return NULL; 25. } 26. void final_function(int first, int second) 27. { int final_score; 28. final_score = first + second ; 29. printf("In final: first = %d, second = %d and final_score = %d\n", first, second, final_score); 30. } 31. void main() 32. { pthread_t thread1, thread2; 33. pthread_create(&thread1, NULL, &first_function, &i); 34. pthread_create(&thread2, NULL, &second_function, &j); 35. pthread_join(thread1, NULL); 36. pthread_join(thread2, NULL); 37. final_function(i,j); 38. } Kết quả hiện ra là In final : first = 10, second = 20 and final_score = 30 đó là số lần lặp các vòng lặp trong hai thread. Sự việc sẽ không còn đơn giản như vậy nữa nếu chúng ta bỏ các lệnh (35) và (36) và khi ấy trên màn hình sẽ hiện ra thông báo: In final : first = 0, second = 0 and final_score = 0 Thông báo này chứng tỏ các thread, tuy có chạy, nhưng không rõ các thông số về chúng ra sao. I.1.3.B Thread, Trình con, và Màn hình. Trong ví dụ sau một trình con được tạo ra để in lên màn hình các số từ 0 đến 9. Một lần gọi [...]... pthread_exit(NULL); /* exit the thread */ return NULL;} int main(int argc, char* argv[]) { int thr_id; /* thread ID for the newly created thread */ pthread_t p _thread; /* thread' s structure */ int a = 1; /* thread 1 identifying number */ int b = 2; /* thread 2 identifying number */ thr_id = pthread_create(&p _thread, NULL, do_loop, (void*)&a); do_loop((void*)&b); pthread_join(p _thread, NULL); return 0;} Trên... pthread_mutex_unlock(&lock1); } void *B() { (5) pthread_mutex_lock(&lock2); // “B” làm việc gì đấy ở đây rất lâu (6) pthread_mutex_lock(&lock1); (7) pthread_mutex_unlock(&lock1); (8) pthread_mutex_unlock(&lock2); } main() { pthread_create( &thread1 , NULL, A, NULL); pthread_create( &thread2 , NULL, B, NULL); } Trên thực tế, khó có thể phân định gianh giới của deadlock tiềm năng và deadlock thật sự Xác... đặt khóa mutex_2 cản trở “”B, còn “B” thì đặt khóa mutext_1 cản trở “A” (1) pthread_mutex_lock(&mutex_1); (2) while (pthread_mutex_trylock(&mutex_2))4 { (3) pthread_mutex_unlock(&mutex_1); /* nơi tắc nghẽn */ (4) pthread_mutex_lock(&mutex_1); } (5) pthread_mutex_unlock(&mutex_2); (6) pthread_mutex_unlock(&mutex_1); 4 pthread_mutex_trylock(&mutex_2) – trả lại ngay giá trị: 0 – “true” – nếu thành... hiện các thông báo của nó ra – và, vì thế mà, chúng ta cũng trông thấy các thông báo của thread ! I.2 Thread Deadlock I.2.1 Khái niệm Deadlock và Stavation Định nghĩa - “Deadlock” là hiện tượng khi mà tất cả các thread mãi mãi ở vào trạng thái chờ vô thời hạn - “Stavation” là hiện tượng khi có một hoặc một vài thread nào đó bị rơi vào trạng thái chờ vô thời hạn Khi hệ thống rơi vào trạng thái “stavation”... hai thread “A” và “B” cùng thực hiện các lệnh như trên vào một thời điểm là rất nhỏ, tuy nhiên chúng vẫn có thể xảy ra Và, sự nguy hiểm là ở chỗ, khi xảy ra thì chương trình sẽ ngừng hoạt động void *A() { (1) pthread_mutex_lock(&lock1); // “A” làm việc gì đấy ở đây rất lâu (2) pthread_mutex_lock(&lock2); (3) pthread_mutex_unlock(&lock2); (4) pthread_mutex_unlock(&lock1); } void *B() { (5) pthread_mutex_lock(&lock2);... right */ pthread_mutex_lock (&chopstick_lock); pthread_mutex_lock (&chopsticks[my_num]); pthread_mutex_lock (&chopsticks[(my_num + 1) % NUM_PHILOSOPHERS]); /* Release the chopstick grabbing lock */ pthread_mutex_unlock (&chopstick_lock); eat (); printf ("Philosopher %d is eating!\n", my_num); /* Put the chopsticks down */ pthread_mutex_unlock (&chopsticks[(my_num + 1) % NUM_PHILOSOPHERS]); pthread_mutex_unlock... the chopsticks down */ pthread_mutex_unlock (&chopsticks[(my_num + 1) % NUM_PHILOSOPHERS]); pthread_mutex_unlock (&chopsticks[my_num]); } return NULL; } int main () { int i; int a[NUM_PHILOSOPHERS]; pthread_t phils[NUM_PHILOSOPHERS]; void* return_val; for (i = 0; i < NUM_PHILOSOPHERS; i++) pthread_mutex_init (&chopsticks[i], NULL); for (i = 0; i < NUM_PHILOSOPHERS; i++) {a[i]=i;pthread_create (&phils[i],... cầm một chiếc! Quyền được nhấc một lúc cả 2 chiếc đĩa được thực hiện thông qua một mutex mới pthread_mutex_lock (&chopstick_lock); dùng để khóa hai lệnh “nhặt đũa” pthread_mutex_lock (&chopstick_lock); pthread_mutex_lock (&chopsticks[my_num]); pthread_mutex_lock (&chopsticks[(my_num + 1) % NUM_PHILOSOPHERS]); pthread_mutex_unlock (&chopstick_lock); không cho ai có thể xem vào giữa Vậy mỗi “triết gia”... thành một thread chạy song song với trình chính “main()” (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) (27) (28) (29) (30) (31) (32) (33) (34) #include #include void* do_loop(void* data) { int i, j; int me = *((int*)data); /* thread identifying number */ for (i=0; i . I.1 Tạo lập thread. I.1.1. Thiết lập Thuộc tính cho thread. 1) pthread_attr_init(&attr); 2) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 3) pthread_create(&threads[0],. của thread cần “join” với trình chính – hay trình chính phải chờ. I.1.2.B Ví dụ về tạo lập & truyền dữ liệu cho thread. Ví dụ 1. Tạo lập thread. Trình chính (thread chính) tạo ra một thread. pk 2-& gt;str_content="World "; pthread_create(& ;thread1 ,NULL,H->test,(void *)pk1); pthread_create(& ;thread2 ,NULL,H->test,(void *)pk2); pthread_join (thread1 , NULL); pthread_join (thread2 ,

Ngày đăng: 04/07/2014, 03:20

TỪ KHÓA LIÊN QUAN

w