例如主線程繼續爲用戶提供服務的同時建立第二個線程
這個線程的做用是將用戶正在編輯的數據進行備份存儲
那麼備份結束以後第二個線程就能夠字節終止
不必再回到主線程中區
稱這樣的線程爲脫離線程,能夠經過修改屬性或者調用pthread_detach的方法來建立
這裏咱們從屬性的角度研究脫離線程linux
1 #include <pthread.h> 2 int pthread_atte_init(pthread_attr_t * attr);
函數的做用是初始化一個線程屬性對象
對應的回收函數是pthread_attr_destory,目的是對屬性對象進行清理和回收
一旦對象被回收了,除非被從新初始化,不然不能再次使用它。
初始化線程屬性對象後,可使用不少其餘的函數來設置不一樣的屬性行爲多線程
1 int pthread_attr_setdetachstate(pthread_attr_t * attr, int detachstate); 2 int pthread_attr_getdetachstate(const pthread_attr_t * attr, int * detachstate);
//set函數可能用到的兩個標誌是PTHREAD_CREATE_JOINABLE和PTHREAD_CREATE_DETACHED
//默認是前者,容許兩個線程從新結合,要是後者的話,不能使用pthread_join來恢復另一個線程的退出狀態異步
1 int pthread_attr_setschedpolicy(pthread_attr_t * attr, int policy); 2 int pthread_attr_getchedpolicy(const pthread_attr_t * attr, int * policy);
//控制線程的調度方式,SCHED_OTHER,SCHED_RP,SCHED_FIFO默認的是第一個。函數
1 int pthread_attr_setschedparm(pthread_attr_t * attr, const struct sched_param * param); 2 int pthread_attr_getschedparam(const pthread_attr_t * attr, struct sched_param * param);
//這個函數能夠對上面的線程的調度進行控制spa
1 int pthread_attr_setinheritsched(pthread_attr_t * attr, int inherit); 2 int pthread_attr_getinheritsched(const pthread_attr_t * attr, int * inherit);
//取值有兩個,PTHREAD_EXPLICIT_SCHED和PTHREAD_INHERIT_SCHED.默認的是第一個
//表示時間分配由屬性明確的設置,要是第二個的話,新線程將沿用其建立者使用的參數線程
1 int pthread_attr_setscope(pthread_attr_t * attr, int scope); 2 int pthread_attr_getscope(const pthread_attr_t * attr, int *scope);
//控制一個線程調度的計算方式,取值目前是惟一的就是PTHREAD_SCOPE_SYSTEM設計
1 int pthread_attr setstacksize(pthread_attr_t * attr, int scope); 2 int pthread_attr_getstacksize(const pthread_attr_t * attr, int * scope);
//這個屬性控制線程建立的棧的大小,單位是字節,屬於POSIX可選的規範。
//linux實現的時候默認的棧都很大,這個功能對linux來講有些多餘
設置脫離狀態屬性程序:指針
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <pthread.h> 5 6 void *thread_function(void *arg); 7 8 char message[] = "Hello World"; 9 int thread_finished = 0; 10 11 int main() { 12 int res; 13 pthread_t a_thread; 14 void *thread_result; 15 pthread_attr_t thread_attr; 16 17 res = pthread_attr_init(&thread_attr);//初始化一個線程屬性對象 18 if (res != 0) { 19 perror("Attribute creation failed"); 20 exit(EXIT_FAILURE); 21 } 22 23 res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); 24 if (res != 0) { 25 perror("Setting detached attribute failed"); 26 exit(EXIT_FAILURE); 27 }//設置屬性對象爲兩個對象不從新結合 28 29 res = pthread_create(&a_thread, &thread_attr, thread_function, (void *)message); 30 if (res != 0) { 31 perror("Thread creation failed"); 32 exit(EXIT_FAILURE); 33 }//建立一個新線程,新線程去執行定義的函數 34 35 (void)pthread_attr_destroy(&thread_attr);//對屬性對象進行清理和回收 36 while(!thread_finished) { 37 printf("Waiting for thread to say it's finished...\n");//先打印一次,去執行新線程 38 sleep(1);//第一秒打印一句,第二秒打印一次,第三秒打印一次 39 } 40 printf("Other thread finished, bye!\n"); 41 exit(EXIT_SUCCESS); 42 } 43 44 void *thread_function(void *arg) { 45 printf("thread_function is running. Argument was %s\n", (char *)arg); 46 sleep(4);//打印一句話,而後等待,第四秒打印下面的一句,全局變量置位 47 printf("Second thread setting finished flag, and exiting now\n"); 48 thread_finished = 1; 49 pthread_exit(NULL); 50 }
程序的執行的效果:code
1 jason@t61:~/c_program/544977-blp3e/chapter12$ gcc thread5.c -o thread5 -lpthread 2 jason@t61:~/c_program/544977-blp3e/chapter12$ ./thread5 3 Waiting for thread to say it's finished... 4 thread_function is running. Argument was Hello World 5 Waiting for thread to say it's finished... 6 Waiting for thread to say it's finished... 7 Waiting for thread to say it's finished... 8 Second thread setting finished flag, and exiting now 9 Other thread finished, bye! 10 jason@t61:~/c_program/544977-blp3e/chapter12$
線程屬性--調度對象
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <pthread.h> 5 6 void *thread_function(void *arg); 7 8 char message[] = "Hello World"; 9 int thread_finished = 0; 10 11 int main() { 12 int res; 13 pthread_t a_thread; 14 void *thread_result; 15 pthread_attr_t thread_attr; 16 17 int max_priority; 18 int min_priority; 19 struct sched_param scheduling_value; 20 21 res = pthread_attr_init(&thread_attr); 22 if (res != 0) { 23 perror("Attribute creation failed"); 24 exit(EXIT_FAILURE); 25 }//初始化一個線程屬性對象 26 27 28 res = pthread_attr_setschedpolicy(&thread_attr, SCHED_OTHER); 29 if (res != 0) { 30 perror("Setting schedpolicy failed"); 31 exit(EXIT_FAILURE); 32 }//設置調度策略 33 34 35 res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); 36 if (res != 0) { 37 perror("Setting detached attribute failed"); 38 exit(EXIT_FAILURE); 39 }//設置爲脫離狀態 40 41 42 res = pthread_create(&a_thread, &thread_attr, thread_function, (void *)message); 43 if (res != 0) { 44 perror("Thread creation failed"); 45 exit(EXIT_FAILURE); 46 }//建立線程 47 48 49 max_priority = sched_get_priority_max(SCHED_OTHER); 50 min_priority = sched_get_priority_min(SCHED_OTHER);//查找容許的優先範圍 51 scheduling_value.sched_priority = min_priority; 52 res = pthread_attr_setschedparam(&thread_attr, &scheduling_value);//對調度策略進行控制 53 if (res != 0) { 54 perror("Setting schedpolicy failed"); 55 exit(EXIT_FAILURE); 56 } 57 58 59 (void)pthread_attr_destroy(&thread_attr);//對屬性對象進行清理和回收 60 61 62 while(!thread_finished) { 63 printf("Waiting for thread to say it's finished...\n"); 64 sleep(1); 65 } 66 printf("Other thread finished, bye!\n"); 67 exit(EXIT_SUCCESS); 68 } 69 70 void *thread_function(void *arg) { 71 printf("thread_function is running. Argument was %s\n", (char *)arg); 72 sleep(4); 73 printf("Second thread setting finished flag, and exiting now\n"); 74 thread_finished = 1; 75 pthread_exit(NULL); 76 }
程序的執行效果:
1 jason@t61:~/c_program/544977-blp3e/chapter12$ ./thread6 2 Waiting for thread to say it's finished... 3 thread_function is running. Argument was Hello World 4 Waiting for thread to say it's finished... 5 Waiting for thread to say it's finished... 6 Waiting for thread to say it's finished... 7 Second thread setting finished flag, and exiting now 8 Other thread finished, bye! 9 jason@t61:~/c_program/544977-blp3e/chapter12$
取消一個線程:
線程能夠在被要求終止時改變其行爲
1 #include <pthread.h> 2 int pthread_cancel(pthread_t thread);
提供一個線程標識符就能夠發送請求取消它
1 #include <pthread.h>//線程用這個函數能夠本身設置本身的取消狀態 2 int pthread_setcancelstate(int state, int * oldstate);
第一個參數能夠是PTHREAD_CANCEL_ENABLE這個值容許線程接收取消請求
或者是PTHREAD_CANCEL_DISABLE做用忽略取消請求
oldstate指針用於獲取先前的取消狀態.默認enable
1 #include <pthread.h> 2 int pthread_setcanceltype(int type, int * oldtype);
type能夠有兩種取值,一個是PTHREAD_CANCEL_ASYNCHRONOUS使得在接收到取消請求時當即採起行動
PTHREAD_CANCEL_DEFERED使得在接收到取消請求後,一致等待直到線程執行了
pthread_join,pthread_cond_wait
pthread_cond_timewait,pthread_testcancel
sem_wait,sigwait
其中之一後才採起行動.默認defered
取消一個線程例程:
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <pthread.h> 5 6 void *thread_function(void *arg); 7 8 int main() { 9 int res; 10 pthread_t a_thread; 11 void *thread_result; 12 13 res = pthread_create(&a_thread, NULL, thread_function, NULL); 14 if (res != 0) { 15 perror("Thread creation failed"); 16 exit(EXIT_FAILURE); 17 } 18 19 sleep(3);//讓新建線程執行三秒 20 printf("Canceling thread...\n"); 21 res = pthread_cancel(a_thread); 22 if (res != 0) { 23 perror("Thread cancelation failed"); 24 exit(EXIT_FAILURE); 25 } 26 27 printf("Waiting for thread to finish...\n"); 28 res = pthread_join(a_thread, &thread_result); 29 if (res != 0) { 30 perror("Thread join failed"); 31 exit(EXIT_FAILURE); 32 } 33 34 exit(EXIT_SUCCESS); 35 } 36 37 void *thread_function(void *arg) { 38 int i, res, j; 39 res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 40 if (res != 0) { 41 perror("Thread pthread_setcancelstate failed"); 42 exit(EXIT_FAILURE); 43 }//容許 44 45 res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); 46 if (res != 0) { 47 perror("Thread pthread_setcanceltype failed"); 48 exit(EXIT_FAILURE); 49 }//異步 50 51 printf("thread_function is running\n"); 52 for(i = 0; i < 10; i++) { 53 printf("Thread is still running (%d)...\n", i); 54 sleep(1); 55 }//線程循環等待被取消 56 pthread_exit(0); 57 }
程序的執行的效果:
1 jason@t61:~/c_program/544977-blp3e/chapter12$ gcc thread7.c -o thread7 -lpthread 2 jason@t61:~/c_program/544977-blp3e/chapter12$ ./thread7 3 thread_function is running 4 Thread is still running (0)... 5 Thread is still running (1)... 6 Thread is still running (2)... 7 Canceling thread... 8 Waiting for thread to finish... 9 jason@t61:~/c_program/544977-blp3e/chapter12$
多線程:
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <pthread.h> 5 6 #define NUM_THREADS 6 7 8 void *thread_function(void *arg); 9 10 int main() { 11 int res; 12 pthread_t a_thread[NUM_THREADS]; 13 void *thread_result; 14 int lots_of_threads; 15 16 for(lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads++) { 17 //作個大循環//循環剛纔的新建過程 18 res = pthread_create(&(a_thread[lots_of_threads]), NULL, thread_function, (void *)&lots_of_threads); 19 if (res != 0) { 20 perror("Thread creation failed"); 21 exit(EXIT_FAILURE); 22 }//建立進程 23 sleep(1);//休眠讓新建進程執行 24 } 25 printf("Waiting for threads to finish...\n");//6個新的線程新建完成以後 26 for(lots_of_threads = NUM_THREADS - 1; lots_of_threads >= 0; lots_of_threads--) { 27 res = pthread_join(a_thread[lots_of_threads], &thread_result); 28 if (res == 0) { 29 printf("Picked up a thread\n"); 30 }//等待回收第6個。而後是第5個 31 else { 32 perror("pthread_join failed"); 33 } 34 } 35 printf("All done\n");//都完成以後打印退出 36 exit(EXIT_SUCCESS); 37 } 38 39 void *thread_function(void *arg) { 40 int my_number = *(int *)arg; 41 int rand_num; 42 43 printf("thread_function is running. Argument was %d\n", my_number);//打印一句話 44 rand_num=1+(int)(9.0*rand()/(RAND_MAX+1.0)); 45 sleep(rand_num);//休眠隨機數秒 46 printf("Bye from %d\n", my_number); 47 pthread_exit(NULL); 48 }
執行效果:
1 jason@t61:~/c_program/544977-blp3e/chapter12$ gcc thread8.c -o thread8 -lpthread 2 jason@t61:~/c_program/544977-blp3e/chapter12$ ./thread8 3 thread_function is running. Argument was 0 4 thread_function is running. Argument was 1 5 thread_function is running. Argument was 2 6 thread_function is running. Argument was 3 7 thread_function is running. Argument was 4 8 Bye from 1 9 thread_function is running. Argument was 5 10 Waiting for threads to finish... 11 Bye from 5 12 Picked up a thread 13 Bye from 0 14 Bye from 2 15 Bye from 3 16 Bye from 4 17 Picked up a thread 18 Picked up a thread 19 Picked up a thread 20 Picked up a thread 21 Picked up a thread 22 All done//執行三次打印的順序都是同樣的!
參考文獻:linux 程序設計
date:2015年 06月 30日 星期二 20:40:07 CST