可以對進程的內存空間和資源進行訪問,並與同一進程中的其他線程共享
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 int main(){ 6 pthread_t thread_id; 7 8 thread_id=pthread_self(); // 返回調用線程的線程ID 9 printf("Thread ID: %lu.\n",thread_id); 10 11 if (pthread_equal(thread_id,pthread_self())) { 12 // if (thread_id==0) { 13 printf("Equal!\n"); 14 } else { 15 printf("Not equal!\n"); 16 } 17 return 0; 18 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 void *thrd_func(void *arg); 6 pthread_t tid; 7 8 int main(){ 9 // 創建線程tid,且線程函數由thrd_func指向,是thrd_func的入口點,即馬上執行此線程函數 10 if (pthread_create(&tid,NULL,thrd_func,NULL)!=0) { 11 printf("Create thread error!\n"); 12 exit(1); 13 } 14 15 printf("TID in pthread_create function: %u.\n",tid); 16 printf("Main process: PID: %d,TID: %u.\n",getpid(),pthread_self()); 17 18 sleep(1); //race 19 20 return 0; 21 } 22 23 void *thrd_func(void *arg){ 24 // printf("I am new thread!\n"); 25 printf("New process: PID: %d,TID: %u.\n",getpid(),pthread_self()); //why pthread_self 26 printf("New process: PID: %d,TID: %u.\n",getpid(),tid); //why pthread_self 27 28 pthread_exit(NULL); //退出線程 29 // return ((void *)0); 30 }
使調用進程終止,所有線程都終止了
等待線程
•由於一個進程中的多個線程是共享數據段的,通常在線程退出之後,退出線程所佔用的資源並不會隨着線程的終止而得到釋放
•pthread_join()函數
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 void *thrd_func1(void *arg); 6 void *thrd_func2(void *arg); 7 8 int main(){ 9 pthread_t tid1,tid2; 10 void *tret; 11 // 創建線程tid1,線程函數thrd_func1 12 if (pthread_create(&tid1,NULL,thrd_func1,NULL)!=0) { 13 printf("Create thread 1 error!\n"); 14 exit(1); 15 } 16 // 創建線程tid2,線程函數thrd_func2 17 if (pthread_create(&tid2,NULL,thrd_func2,NULL)!=0) { 18 printf("Create thread 2 error!\n"); 19 exit(1); 20 } 21 // 等待線程tid1結束,線程函數返回值放在tret中 22 if (pthread_join(tid1,&tret)!=0){ 23 printf("Join thread 1 error!\n"); 24 exit(1); 25 } 26 27 printf("Thread 1 exit code: %d.\n",(int *)tret); 28 // 等待tid2結束,線程函數返回值放在tret中 29 if (pthread_join(tid2,&tret)!=0){ 30 printf("Join thread 2 error!\n"); 31 exit(1); 32 } 33 34 printf("Thread 2 exit code: %d.\n",(int *)tret); 35 36 return 0; 37 } 38 39 void *thrd_func1(void *arg){ 40 printf("Thread 1 returning!\n"); 41 // sleep(3); 42 return ((void *)1); // 自動退出線程 43 } 44 45 void *thrd_func2(void *arg){ 46 printf("Thread 2 exiting!\n"); 47 pthread_exit((void *)2); // 線程主動退出,返回(void *)2 48 }
取消線程
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 void *thrd_func1(void *arg); 6 void *thrd_func2(void *arg); 7 8 pthread_t tid1,tid2; 9 10 int main(){ 11 // 創建線程tid1,線程函數thrd_func1 12 if (pthread_create(&tid1,NULL,thrd_func1,NULL)!=0) { 13 printf("Create thread 1 error!\n"); 14 exit(1); 15 } 16 // 創建線程tid2,線程函數thrd_func2 17 if (pthread_create(&tid2,NULL,thrd_func2,NULL)!=0) { 18 printf("Create thread 2 error!\n"); 19 exit(1); 20 } 21 // 等待線程tid1退出 22 if (pthread_join(tid1,NULL)!=0){ 23 printf("Join thread 1 error!\n"); 24 exit(1); 25 }else 26 printf("Thread 1 Joined!\n"); 27 // 等待線程tid2退出 28 if (pthread_join(tid2,NULL)!=0){ 29 printf("Join thread 2 error!\n"); 30 exit(1); 31 }else 32 printf("Thread 2 Joined!\n"); 33 34 return 0; 35 } 36 37 void *thrd_func1(void *arg){ 38 // pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); 39 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); // 設置其他線程可以cancel掉此線程 40 41 while(1) { 42 printf("Thread 1 is running!\n"); 43 sleep(1); 44 } 45 pthread_exit((void *)0); 46 } 47 48 void *thrd_func2(void *arg){ 49 printf("Thread 2 is running!\n"); 50 sleep(5); 51 if (pthread_cancel(tid1)==0) // 線程tid2向線程tid1發送cancel 52 printf("Send Cancel cmd to Thread 1.\n"); 53 54 pthread_exit((void *)0); 55 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 #define THREAD_NUM 3 6 #define REPEAT_TIMES 5 7 #define DELAY 4 8 9 void *thrd_func(void *arg); 10 11 int main(){ 12 pthread_t thread[THREAD_NUM]; 13 int no; 14 void *tret; 15 16 srand((int)time(0)); // 初始化隨機函數發生器 17 18 for(no=0;no<THREAD_NUM;no++){ 19 if (pthread_create(&thread[no],NULL,thrd_func,(void*)no)!=0) { // 創建THREAD_NUM個線程,傳入(void*)no作爲thrd_func的參數 20 printf("Create thread %d error!\n",no); 21 exit(1); 22 } else 23 printf("Create thread %d success!\n",no); 24 } 25 26 for(no=0;no<THREAD_NUM;no++){ 27 if (pthread_join(thread[no],&tret)!=0){ // 等待thread[no]線程結束,線程函數返回值放在tret中 28 printf("Join thread %d error!\n",no); 29 exit(1); 30 }else 31 printf("Join thread %d success!\n",no); 32 } 33 34 return 0; 35 } 36 37 void *thrd_func(void *arg){ 38 int thrd_num=(void*)arg; 39 int delay_time=0; 40 int count=0; 41 42 printf("Thread %d is starting.\n",thrd_num); 43 for(count=0;count<REPEAT_TIMES;count++) { 44 delay_time=(int)(DELAY*(rand()/(double)RAND_MAX))+1; 45 sleep(delay_time); 46 printf("\tThread %d:job %d delay =%d.\n",thrd_num,count,delay_time); 47 } 48 49 printf("Thread %d is exiting.\n",thrd_num); 50 pthread_exit(NULL); 51 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 5 #define THREAD_NUM 3 6 #define REPEAT_TIMES 5 7 #define DELAY 4 8 9 pthread_mutex_t mutex; 10 11 void *thrd_func(void *arg); 12 13 int main(){ 14 pthread_t thread[THREAD_NUM]; 15 int no; 16 void *tret; 17 18 srand((int)time(0)); 19 // 創建快速互斥鎖(默認),鎖的編號返回給mutex 20 pthread_mutex_init(&mutex,NULL); 21 22 // 創建THREAD_NUM個線程,每個線程號返回給&thread[no],每個線程的入口函數均爲thrd_func,參數爲 23 for(no=0;no<THREAD_NUM;no++){ 24 if (pthread_create(&thread[no],NULL,thrd_func,(void*)no)!=0) { 25 printf("Create thread %d error!\n",no); 26 exit(1); 27 } else 28 printf("Create thread %d success!\n",no); 29 } 30 31 // 對每個線程進行join,返回值給tret 32 for(no=0;no<THREAD_NUM;no++){ 33 if (pthread_join(thread[no],&tret)!=0){ 34 printf("Join thread %d error!\n",no); 35 exit(1); 36 }else 37 printf("Join thread %d success!\n",no); 38 } 39 // 消除互斥鎖 40 pthread_mutex_destroy(&mutex); 41 return 0; 42 } 43 44 void *thrd_func(void *arg){ 45 int thrd_num=(void*)arg; // 傳入的參數,互斥鎖的編號 46 int delay_time,count; 47 48 // 對互斥鎖上鎖 49 if(pthread_mutex_lock(&mutex)!=0) { 50 printf("Thread %d lock failed!\n",thrd_num); 51 pthread_exit(NULL); 52 } 53 54 printf("Thread %d is starting.\n",thrd_num); 55 for(count=0;count<REPEAT_TIMES;count++) { 56 delay_time=(int)(DELAY*(rand()/(double)RAND_MAX))+1; 57 sleep(delay_time); 58 printf("\tThread %d:job %d delay =%d.\n",thrd_num,count,delay_time); 59 } 60 61 printf("Thread %d is exiting.\n",thrd_num); 62 // 解鎖 63 pthread_mutex_unlock(&mutex); 64 65 pthread_exit(NULL); 66 }
和上一版本的程序差異在於有沒有鎖,有鎖的情況下,必須等"thread x is exiting."之後其他線程才能繼續。
eg. 同步各線程,執行順序爲逆序。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 #include <semaphore.h> 5 6 #define THREAD_NUM 3 7 #define REPEAT_TIMES 5 8 #define DELAY 4 9 10 sem_t sem[THREAD_NUM]; 11 12 void *thrd_func(void *arg); 13 14 int main(){ 15 pthread_t thread[THREAD_NUM]; 16 int no; 17 void *tret; 18 19 srand((int)time(0)); 20 21 // 初始化THREAD_NUM-1個信號量,均初始化爲0 22 for(no=0;no<THREAD_NUM-1;no++){ 23 sem_init(&sem[no],0,0); 24 } 25 26 // sem[2]信號量初始化爲1,即sem數組中最後一個信號量 27 sem_init(&sem[2],0,1); 28 29 // 創建THREAD_NUM個線程,入口函數均爲thrd_func,參數爲(void*)no 30 for(no=0;no<THREAD_NUM;no++){ 31 if (pthread_create(&thread[no],NULL,thrd_func,(void*)no)!=0) { 32 printf("Create thread %d error!\n",no); 33 exit(1); 34 } else 35 printf("Create thread %d success!\n",no); 36 } 37 38 // 逐個join掉THREAD_NUM個線程 39 for(no=0;no<THREAD_NUM;no++){ 40 if (pthread_join(thread[no],&tret)!=0){ 41 printf("Join thread %d error!\n",no); 42 exit(1); 43 }else 44 printf("Join thread %d success!\n",no); 45 } 46 47 // 逐個取消信號量 48 for(no=0;no<THREAD_NUM;no++){ 49 sem_destroy(&sem[no]); 50 } 51 52 return 0; 53 } 54 55 void *thrd_func(void *arg){ 56 int thrd_num=(void*)arg; // 參數no 57 int delay_time,count; 58 59 // 帶有阻塞的p操作 60 sem_wait(&sem[thrd_num]); 61 62 63 printf("Thread %d is starting.\n",thrd_num); 64 for(count=0;count<REPEAT_TIMES;count++) { 65 delay_time=(int)(DELAY*(rand()/(double)RAND_MAX))+1; 66 sleep(delay_time); 67 printf("\tThread %d:job %d delay =%d.\n",thrd_num,count,delay_time); 68 } 69 70 printf("Thread %d is exiting.\n",thrd_num); 71 72 // 對前一個信號量進行V操作 73 // 由於只有最後一個信號量初始化爲1,其餘均爲0 74 // 故線程執行的順序將爲逆序 75 sem_post(&sem[(thrd_num+THREAD_NUM-1)%THREAD_NUM]); 76 77 pthread_exit(NULL); // 線程主動結束 78 }