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


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

    称这样的线程为脱离线程,可以通过修改属性或者调用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


    万事走心 精益求美


  • 相关阅读:
    sync.WaitGroup golang并发调度器
    Golang New 关键字的小bug 未找到原因(暂时)
    zabbix监控websphere的几个监控项
    zabbix监控AIX DB2数据库
    NOIP2008P 排座椅
    解题报告—— 2018级2016第二学期第五周作业 删数问题
    解题报告——2018级2016第二学期第五周作业排座椅
    解题报告——2018级2016第二学期第四周作业 (2的幂次方)
    解题报告——-2018级2016第二学期第三周作业
    解题报告——2018级2016第二学期第二周作业
  • 原文地址:https://www.cnblogs.com/kongchung/p/4611541.html
Copyright © 2020-2023  润新知