zoukankan      html  css  js  c++  java
  • 【Linux 线程】常用线程函数复习《二》

    1、函数pthread_join

     1 /*************************************************************************
     2     > File Name: pthread_join1.c
     3     > Summary: pthread_join函数的基本用法
     4     > Author: xuelisheng 
     5     > Created Time: 2018年12月13日 
     6  ************************************************************************/
     7 
     8 #include <stdio.h>
     9 #include <stdlib.h>
    10 #include <string.h>
    11 #include <unistd.h>
    12 #include <errno.h>
    13 #include <pthread.h>
    14 
    15 struct thrd
    16 {
    17     int var;
    18     char str[256];
    19 };
    20 
    21 void *tfn(void *arg)
    22 {
    23     struct thrd *tval;
    24     tval = malloc(sizeof(tval));
    25 
    26     tval->var = 100;
    27     strcpy(tval->str, "hello xls");
    28     return (void *)tval;
    29 }
    30 
    31 int main()
    32 {
    33     pthread_t tid;
    34     struct thrd *retval;
    35     int ret = pthread_create(&tid, NULL, tfn, NULL);
    36     if(ret != 0)
    37     {
    38         printf("create thread fail
    ");
    39     }
    40     /*
    41     函数pthread_join用来等待一个线程的结束,线程间同步的操作。头文件 : #include <pthread.h>
    42     函数定义: int pthread_join(pthread_t thread, void **retval);
    43     描述 :pthread_join()函数,以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。
    44     参数 :thread: 线程标识符,即线程ID,标识唯一线程。retval: 用户定义的指针,用来存储被等待线程的返回值。
    45     返回值 : 0代表成功。 失败,返回的则是错误号。
    46     */
    47     ret = pthread_join(tid, (void **)&retval);
    48     printf("child thread exit and return values var = %d, str = %s
    ",  retval->var, retval->str);
    49     pthread_exit(NULL);
    50     return 0;
    51 }

    运行结果:

    child thread exit and return values var = 100, str = hello xls

    2、函数pthread_cancel

     1 /*************************************************************************
     2     > File Name: pthread_cancel1.c
     3     > Summary: 终止线程的函数 pthread_cancel()
     4     > Author: xuelisheng 
     5     > Created Time: 2018年12月13日 
     6  ************************************************************************/
     7 
     8 #include <stdio.h>
     9 #include <stdlib.h>
    10 #include <string.h>
    11 #include <unistd.h>
    12 #include <errno.h>
    13 #include <pthread.h>
    14 
    15 void *tfn(void *arg)
    16 {
    17     while(1)
    18     {
    19         printf("thread :pid = %d, tid = %lu
    ",getpid(), pthread_self());
    20         sleep(1);
    21     }
    22     return NULL;
    23 }
    24 
    25 int main()
    26 {
    27     pthread_t tid;
    28     int ret  = pthread_create(&tid, NULL, tfn, NULL);
    29     if(ret != 0)
    30     {
    31         printf("pthread_create fail
    ");
    32         exit(1);
    33     }
    34     printf("main: pid = %d, tid = %lu
    ",getpid(), pthread_self());
    35 
    36     sleep(5);
    37 
    38     /*
    39     #include<pthread.h>
    40     int pthread_cancel(pthread_t thread)
    41     发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。
    42     若是在整个程序退出时,要终止各个线程,应该在成功发送 CANCEL 指令后,使用 pthread_join 函数,等待指定的线程已经完全退出以后,再继续执行;否则,很容易产生 “段错误”。
    43     */
    44     ret = pthread_cancel(tid);        // 终止线程tid
    45     if(ret != 0)
    46     {
    47         printf("pthread_cancel fail
    ");
    48         exit(1);
    49     }
    50 
    51     while(1);
    52 53 
    54     return 0;
    55 }

    运行结果:

    thread :pid = 20038, tid = 139963255736064
    main: pid = 20038, tid = 139963264071424
    thread :pid = 20038, tid = 139963255736064
    thread :pid = 20038, tid = 139963255736064
    thread :pid = 20038, tid = 139963255736064
    thread :pid = 20038, tid = 139963255736064
    (循环等待)

    3、3种终止线程的方式:exit()、pthread_exit()、pthread_cancel

    情形1:

     1 /*************************************************************************
     2     > File Name: pthread_cancel2.c
     3     > Summary: 终止线程的3种方式:exit、pthread_exit()、 pthread_cancel()
     4     > Author: xuelisheng 
     5     > Created Time: 2018年12月13日 
     6  ************************************************************************/
     7 
     8 #include <stdio.h>
     9 #include <stdlib.h>
    10 #include <string.h>
    11 #include <unistd.h>
    12 #include <errno.h>
    13 #include <pthread.h>
    14 
    15 void *tfn1(void *arg)
    16 {
    17     printf("thread 1 returning
    ");
    18     return (void *)111;        // 线程函数中,这里的return (void *)111相当于 exit(111)
    19 }
    20 
    21 void *tfn2(void *arg)
    22 {
    23     printf("thread 2 exiting
    ");
    24     pthread_exit((void *)222);
    25 }
    26 
    27 void *tfn3(void *arg)
    28 {
    29     while(1)
    30     {
    31         printf("thread 3:  I'm going to die in 3 seconds ...
    ");
    32         sleep(1);
    33         /*pthread_testcanel();  // 自己添加取消点*/
    34     }
    35     return (void *)666;
    36 }
    37 int main()
    38 {
    39     pthread_t tid;
    40     void *tret = NULL;
    41 
    42     pthread_create(&tid, NULL, tfn1, NULL);
    43     pthread_join(tid, &tret);
    44     printf("thread 1 exit code = %d
    
    ", (int)tret);
    45 
    46     pthread_create(&tid, NULL, tfn2, NULL);
    47     pthread_join(tid, &tret);
    48     printf("thread 2 exit code = %d
    
    ", (int)tret);
    49 
    50     pthread_create(&tid, NULL, tfn3, NULL);
    51     sleep(3);                    // 主线程休眠3秒
    52     pthread_cancel(tid);
    53     pthread_join(tid, &tret);                // 主线程要回收子线程3,但是子线程3之前已经被cancel,tret所以返回值-1(表示失败)
    54     printf("thread 3 exit code = %d
    
    ", (int)tret);
    55 
    56     return 0;
    57 }

    运行结果:

    thread 1 returning
    thread 1 exit code = 111
    
    thread 2 exiting
    thread 2 exit code = 222
    
    thread 3:  I'm going to die in 3 seconds ...
    thread 3:  I'm going to die in 3 seconds ...
    thread 3:  I'm going to die in 3 seconds ...
    thread 3 exit code = -1

    情形2:当pthread_cancel要终止的线程没有陷入内核的操作

     1 /*************************************************************************
     2     > File Name: pthread_cancel3.c
     3     > Summary: 终止线程的3种方式:exit、pthread_exit()、 pthread_cancel()    当pthread_cancel要终止的线程没有陷入内核的操作
     4     > Author: xuelisheng 
     5     > Created Time: 2018年12月13日 
     6  ************************************************************************/
     7 
     8 #include <stdio.h>
     9 #include <stdlib.h>
    10 #include <string.h>
    11 #include <unistd.h>
    12 #include <errno.h>
    13 #include <pthread.h>
    14 
    15 void *tfn1(void *arg)
    16 {
    17     printf("thread 1 returning
    ");
    18     return (void *)111;        // 线程函数中,这里的return (void *)111相当于 exit(111)
    19 }
    20 
    21 void *tfn2(void *arg)
    22 {
    23     printf("thread 2 exiting
    ");
    24     pthread_exit((void *)222);
    25 }
    26 
    27 void *tfn3(void *arg)
    28 {
    29     while(1)                // 终止的线程中没有陷入内核的操作(例如系统调用等)
    30     {
    31         //printf("thread 3:  I'm going to die in 3 seconds ...
    ");
    32         //sleep(1);
    33         /*pthread_testcanel();  // 自己添加取消点*/
    34     }
    35     return (void *)666;
    36 }
    37 int main()
    38 {
    39     pthread_t tid;
    40     void *tret = NULL;
    41 
    42     pthread_create(&tid, NULL, tfn1, NULL);
    43     pthread_join(tid, &tret);
    44     printf("thread 1 exit code = %d
    
    ", (int)tret);
    45 
    46     pthread_create(&tid, NULL, tfn2, NULL);
    47     pthread_join(tid, &tret);
    48     printf("thread 2 exit code = %d
    
    ", (int)tret);
    49 
    50     pthread_create(&tid, NULL, tfn3, NULL);
    51     sleep(3);                    // 主线程休眠3秒
    52     pthread_cancel(tid);
    53     pthread_join(tid, &tret);                // 主线程要回收子线程3,但是子线程3之前已经被cancel,tret所以返回值-1(表示失败)
    54     printf("thread 3 exit code = %d
    
    ", (int)tret);
    55 
    56     return 0;
    57 }

    运行结果:

    thread 1 returning
    thread 1 exit code = 111
    
    thread 2 exiting
    thread 2 exit code = 222
    (光标在此while循环...)

    情形3:解决当pthread_cancel要终止的线程没有陷入内核的操作---创建线程取消点

     1 /*************************************************************************
     2     > File Name: pthread_cancel4.c
     3     > Summary: 终止线程的3种方式:exit、pthread_exit()、 pthread_cancel()    解决当pthread_cancel要终止的线程没有陷入内核的操作
     4     > Author: xuelisheng 
     5     > Created Time: 2018年12月13日 
     6  ************************************************************************/
     7 
     8 #include <stdio.h>
     9 #include <stdlib.h>
    10 #include <string.h>
    11 #include <unistd.h>
    12 #include <errno.h>
    13 #include <pthread.h>
    14 
    15 void *tfn1(void *arg)
    16 {
    17     printf("thread 1 returning
    ");
    18     return (void *)111;        // 线程函数中,这里的return (void *)111相当于 exit(111)
    19 }
    20 
    21 void *tfn2(void *arg)
    22 {
    23     printf("thread 2 exiting
    ");
    24     pthread_exit((void *)222);
    25 }
    26 
    27 void *tfn3(void *arg)
    28 {
    29     while(1)                // 终止的线程中没有陷入内核的操作(例如系统调用等),可以添加函数pthread_testcanel()
    30     {
    31         //printf("thread 3:  I'm going to die in 3 seconds ...
    ");
    32         //sleep(1);
    33         pthread_testcancel();  // 自己添加取消点            
    34     }
    35     return (void *)666;
    36 }
    37 int main()
    38 {
    39     pthread_t tid;
    40     void *tret = NULL;
    41 
    42     pthread_create(&tid, NULL, tfn1, NULL);
    43     pthread_join(tid, &tret);
    44     printf("thread 1 exit code = %d
    
    ", (int)tret);
    45 
    46     pthread_create(&tid, NULL, tfn2, NULL);
    47     pthread_join(tid, &tret);
    48     printf("thread 2 exit code = %d
    
    ", (int)tret);
    49 
    50     pthread_create(&tid, NULL, tfn3, NULL);
    51     sleep(3);                    // 主线程休眠3秒
    52     pthread_cancel(tid);
    53     pthread_join(tid, &tret);                // 主线程要回收子线程3,但是子线程3之前已经被cancel,tret所以返回值-1(表示失败)
    54     printf("thread 3 exit code = %d
    
    ", (int)tret);
    55 
    56     return 0;
    57 }

    运行结果:

    thread 1 returning
    thread 1 exit code = 111
    
    thread 2 exiting
    thread 2 exit code = 222
    
    thread 3 exit code = -1
  • 相关阅读:
    VUE处理项目中的ESLint语法报错问题
    通过Focas连接Fanuc的NC Guide
    IdentityServer
    Dapper2.0.78手册翻译
    Framework项目持续集成(jenkins)及集合SonarQube
    基于 GitBook 搭建个人博客
    GitBook 常用插件
    Vue管理系统前端系列六动态路由-权限管理实现
    Vue管理系统前端系列五自定义主题
    Vue管理系统前端系列四组件拆分封装
  • 原文地址:https://www.cnblogs.com/xuelisheng/p/10116182.html
Copyright © 2011-2022 走看看