线程学习第二课--脱离线程,调度线程,取消线程,多线程

例如主线程继续为用户提供服务的同时创建第二个线程
这个线程的作用是将用户正在编辑的数据进行备份存储
那么备份结束之后第二个线程就可以字节终止
没必要再回到主线程中区

称这样的线程为脱离线程,可以通过修改属性或者调用pthread_detach的方法来创建
这里我们从属性的角度研究脱离线程

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);

//这个函数可以对上面的线程的调度进行控制

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...
");//先打印一次,去执行新线程
38         sleep(1);//第一秒打印一句,第二秒打印一次,第三秒打印一次
39     }
40     printf("Other thread finished, bye!
");
41     exit(EXIT_SUCCESS);
42 }
43 
44 void *thread_function(void *arg) {
45     printf("thread_function is running. Argument was %s
", (char *)arg);
46     sleep(4);//打印一句话,然后等待,第四秒打印下面的一句,全局变量置位
47     printf("Second thread setting finished flag, and exiting now
");
48     thread_finished = 1;
49     pthread_exit(NULL);
50 }


程序的执行的效果:

 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...
");
64         sleep(1);
65     }
66     printf("Other thread finished, bye!
");
67     exit(EXIT_SUCCESS);
68 }
69 
70 void *thread_function(void *arg) {
71     printf("thread_function is running. Argument was %s
", (char *)arg);
72     sleep(4);
73     printf("Second thread setting finished flag, and exiting now
");
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...
");
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...
");
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
");
52     for(i = 0; i < 10; i++) {
53         printf("Thread is still running (%d)...
", 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...
");//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
");
30         }//等待回收第6个。然后是第5个
31         else {
32             perror("pthread_join failed");
33         }
34     }
35     printf("All done
");//都完成之后打印退出
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
", my_number);//打印一句话
44     rand_num=1+(int)(9.0*rand()/(RAND_MAX+1.0));
45     sleep(rand_num);//休眠随机数秒
46     printf("Bye from %d
", 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


万事走心 精益求美


原文地址:https://www.cnblogs.com/kongchung/p/4611541.html