線程學習第二課--脫離線程,調度線程,取消線程,多線程

例如主線程繼續爲用戶提供服務的同時建立第二個線程
這個線程的做用是將用戶正在編輯的數據進行備份存儲
那麼備份結束以後第二個線程就能夠字節終止
不必再回到主線程中區

稱這樣的線程爲脫離線程,能夠經過修改屬性或者調用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

相關文章
相關標籤/搜索