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

    1、pthread_create以及pthread_self函数

     1 /*************************************************************************
     2     > File Name: pthread1.c
     3     > Summary: 两个函数的使用:pthread_create() 以及函数 pthread_self()
     4     > Author: xuelisheng 
     5     > Created Time: 2018年12月13日 
     6  ************************************************************************/
     7 
     8 #include<stdio.h>
     9 #include<stdlib.h>
    10 #include<pthread.h>
    11 
    12 void *callBack()
    13 {
    14     // pthread_self():用来获得线程id。返回值为线程id,没有参数。
    15     printf("pthread_self return value = %lu", pthread_self());
    16     return NULL;
    17 }
    18 
    19 int main()
    20 {
    21     pthread_t pid;
    22     /*
    23     pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
    24     参数1:pthread_t tid;   传出参数,指向线程标识符的指针。      &tid
    25     参数2:属性  NULL
    26     参数3:回调函数的函数指针。
    27     参数4:回调函数的参数列表。没有的话传NULL
    28     */
    29     int ret = pthread_create(&pid,NULL,callBack,NULL);
    30     if(ret != 0)
    31     {
    32         printf("pthread_create fail
    ");
    33         exit(-1);
    34     }
    35     //阻塞主线程一会
    36     sleep(1);
    37     return 0;
    38 }

    运行结果:

    pthread_self return value = 140083744417536

    2、循环创建多个子线程

    第一种情况:

     1 /*************************************************************************
     2     > File Name: pthread2.c
     3     > Summary: pthread_create() 循环创建多个线程
     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 *callBack(void *arg)
    16 {
    17     int i = (int)arg;
    18     sleep(i);
    19     // pthread_self():用来获得线程id。返回值为线程id,没有参数。
    20     printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu
    ", i+1, getpid(), pthread_self());
    21     return NULL;
    22 }
    23 
    24 int main()
    25 {
    26     pthread_t pid;
    27     /*
    28     pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
    29     参数1:pthread_t tid;   传出参数,指向线程标识符的指针。      &tid
    30     参数2:属性  null
    31     参数3:回调函数的函数指针。
    32     参数4:回调函数的参数列表。没有的话传NULL
    33     */
    34     int i;
    35     for(i = 0; i<5; i++)
    36     {
    37         int ret = pthread_create(&pid,NULL,callBack, (void *)i);
    38         if(ret != 0)
    39         {
    40             printf("pthread_create fail
    ");
    41             exit(-1);
    42         }
    43     }
    44     
    45     //阻塞主线程一会
    46     sleep(i);
    47     printf("i am main thread,getpid() = %d,pthread_self return value = %lu
    ", getpid(), pthread_self());
    48     return 0;
    49 }

    运行结果:

    1 i am 1 th thread,getpid() = 10595,pthread_self return value = 140194122020608
    2 i am 2 th thread,getpid() = 10595,pthread_self return value = 140194113627904
    3 i am 3 th thread,getpid() = 10595,pthread_self return value = 140194105235200
    4 i am 4 th thread,getpid() = 10595,pthread_self return value = 140194096842496
    5 i am 5 th thread,getpid() = 10595,pthread_self return value = 140194088449792
    6 i am main thread,getpid() = 10595,pthread_self return value = 140194130355968

    第二种情况:

     1 /*************************************************************************
     2     > File Name: pthread3.c
     3     > Summary: pthread_create() 循环创建多个线程(第二种情况)
     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 *callBack(void *arg)
    16 //{
    17 //    int i = (int)arg;
    18 void *callBack(void *arg)
    19 {
    20     int i = *((int *)arg);
    21     sleep(i);
    22     // pthread_self():用来获得线程id。返回值为线程id,没有参数。
    23     printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu
    ", i+1, getpid(), pthread_self());
    24     return NULL;
    25 }
    26 
    27 int main()
    28 {
    29     pthread_t pid;
    30     /*
    31     pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
    32     参数1:pthread_t tid;   传出参数,指向线程标识符的指针。      &tid
    33     参数2:属性  null
    34     参数3:回调函数的函数指针。
    35     参数4:回调函数的参数列表。没有的话传NULL
    36     */
    37     int i;
    38     for(i = 0; i<5; i++)
    39     {
    40         //int ret = pthread_create(&pid,NULL,callBack, (void *)i);
    41         int ret = pthread_create(&pid,NULL,callBack, (void *)&i);       //注意这里如果取地址,主线程的i不断变化,所以取到的i值出现混乱
    42         if(ret != 0)
    43         {
    44             printf("pthread_create fail
    ");
    45             exit(-1);
    46         }
    47     }
    48     
    49     //阻塞主线程一会
    50     sleep(i);
    51     printf("i am main thread,getpid() = %d,pthread_self return value = %lu
    ", getpid(), pthread_self());
    52     return 0;
    53 }

    运行结果:

    1 i am 3 th thread,getpid() = 11433,pthread_self return value = 140484748015360
    2 i am 4 th thread,getpid() = 11433,pthread_self return value = 140484739622656
    3 i am 4 th thread,getpid() = 11433,pthread_self return value = 140484731229952
    4 i am 5 th thread,getpid() = 11433,pthread_self return value = 140484722837248
    5 i am main thread,getpid() = 11433,pthread_self return value = 140484756350720

    3、线程间全局变量共享

     1 /*************************************************************************
     2     > File Name: pthread4.c
     3     > Summary: 线程间全局变量共享 验证
     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 // 定义全局变量
    16 int var = 100;
    17 void *callBack()
    18 {
    19     var = 200;
    20     printf("child thread running now var  = %d
    ", var);
    21     return NULL;
    22 }
    23 
    24 int main()
    25 {
    26     printf("before child thread create var = %d
    ", var);
    27     pthread_t pid;
    28     /*
    29     pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
    30     参数1:pthread_t tid;   传出参数,指向线程标识符的指针。      &tid
    31     参数2:属性  null
    32     参数3:回调函数的函数指针。
    33     参数4:回调函数的参数列表。没有的话传NULL
    34     */
    35     int ret = pthread_create(&pid,NULL,callBack, NULL);
    36     if(ret != 0)
    37     {
    38         printf("pthread_create fail
    ");        
    39         exit(-1);
    40     }
    41     //阻塞主线程一会
    42     sleep(1);
    43     printf("after child thread over now var = %d
    ", var);
    44     return 0;
    45 }

    运行结果:

    1 before child thread create var = 100
    2 child thread running now var  = 200
    3 after child thread over now var = 200

    4、函数pthread_exit()

    情形一:

     1 /*************************************************************************
     2     > File Name: pthread5.c
     3     > Summary: pthread_exit函数之  使用exit函数退出线程
     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 *callBack(void *arg)
    16 {
    17     int i = (int)arg;
    18     sleep(i);
    19     if(i == 2){
    20         exit(0);
    21     }
    22     
    23     // pthread_self():用来获得线程id。返回值为线程id,没有参数。
    24     printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu
    ", i+1, getpid(), pthread_self());
    25     return NULL;
    26 }
    27 
    28 int main()
    29 {
    30     pthread_t pid;
    31     /*
    32     pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
    33     参数1:pthread_t tid;   传出参数,指向线程标识符的指针。      &tid
    34     参数2:属性  null
    35     参数3:回调函数的函数指针。
    36     参数4:回调函数的参数列表。没有的话传NULL
    37     */
    38     int i;
    39     for(i = 0; i<5; i++)
    40     {
    41         int ret = pthread_create(&pid,NULL,callBack, (void *)i);
    42         if(ret != 0)
    43         {
    44             printf("pthread_create fail
    ");
    45             exit(-1);
    46         }
    47     }
    48     
    49     //阻塞主线程一会
    50     sleep(i);
    51     printf("i am main thread,getpid() = %d,pthread_self return value = %lu
    ", getpid(), pthread_self());
    52     return 0;
    53 }

    运行结果:

    i am 1 th thread,getpid() = 14603,pthread_self return value = 139796530956032
    i am 2 th thread,getpid() = 14603,pthread_self return value = 139796522563328

    使用exit函数退出线程:exit()进程退出,如果在线程函数中调用exit,那改线程的进程也就挂了,会导致该线程所在进程的其他线程也挂掉,比较严重。

    情形2-1:使用return 退出线程

     1 /*************************************************************************
     2     > File Name: pthread6.c
     3     > Summary: pthread_exit函数之 使用return 退出线程
     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 *callBack(void *arg)
    16 {
    17     int i = (int)arg;
    18     sleep(i);
    19     if(i == 2){
    20         return NULL;
    21     }
    22     
    23     // pthread_self():用来获得线程id。返回值为线程id,没有参数。
    24     printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu
    ", i+1, getpid(), pthread_self());
    25     return NULL;
    26 }
    27 
    28 int main()
    29 {
    30     pthread_t pid;
    31     /*
    32     pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
    33     参数1:pthread_t tid;   传出参数,指向线程标识符的指针。      &tid
    34     参数2:属性  null
    35     参数3:回调函数的函数指针。
    36     参数4:回调函数的参数列表。没有的话传NULL
    37     */
    38     int i;
    39     for(i = 0; i<5; i++)
    40     {
    41         int ret = pthread_create(&pid,NULL,callBack, (void *)i);
    42         if(ret != 0)
    43         {
    44             printf("pthread_create fail
    ");
    45             exit(-1);
    46         }
    47     }
    48     
    49     //阻塞主线程一会
    50     sleep(i);
    51     printf("i am main thread,getpid() = %d,pthread_self return value = %lu
    ", getpid(), pthread_self());
    52     return 0;
    53 }

    运行结果:(正常)

    1 i am 1 th thread,getpid() = 15009,pthread_self return value = 140509750220544
    2 i am 2 th thread,getpid() = 15009,pthread_self return value = 140509741827840
    3 i am 4 th thread,getpid() = 15009,pthread_self return value = 140509725042432
    4 i am 5 th thread,getpid() = 15009,pthread_self return value = 140509716649728
    5 i am main thread,getpid() = 15009,pthread_self return value = 140509758555904

    情形2-2:使用return 退出线程(嵌套)

     1 /*************************************************************************
     2     > File Name: pthread7.c
     3     > Summary: pthread_exit函数之 使用return 退出线程(嵌套)
     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 *fun(){
    16     return NULL;
    17 }
    18 
    19 void *callBack(void *arg)
    20 {
    21     int i = (int)arg;
    22     sleep(i);
    23     if(i == 2){
    24         fun();
    25     }
    26     
    27     // pthread_self():用来获得线程id。返回值为线程id,没有参数。
    28     printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu
    ", i+1, getpid(), pthread_self());
    29     return NULL;
    30 }
    31 
    32 int main()
    33 {
    34     pthread_t pid;
    35     /*
    36     pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
    37     参数1:pthread_t tid;   传出参数,指向线程标识符的指针。      &tid
    38     参数2:属性  null
    39     参数3:回调函数的函数指针。
    40     参数4:回调函数的参数列表。没有的话传NULL
    41     */
    42     int i;
    43     for(i = 0; i<5; i++)
    44     {
    45         int ret = pthread_create(&pid,NULL,callBack, (void *)i);
    46         if(ret != 0)
    47         {
    48             printf("pthread_create fail
    ");
    49             exit(-1);
    50         }
    51     }
    52     
    53     //阻塞主线程一会
    54     sleep(i);
    55     printf("i am main thread,getpid() = %d,pthread_self return value = %lu
    ", getpid(), pthread_self());
    56     return 0;
    57 }

    运行结果:(不正常)

    i am 1 th thread,getpid() = 15242,pthread_self return value = 140151373674240
    i am 2 th thread,getpid() = 15242,pthread_self return value = 140151365281536
    i am 3 th thread,getpid() = 15242,pthread_self return value = 140151356888832
    i am 4 th thread,getpid() = 15242,pthread_self return value = 140151348496128
    i am 5 th thread,getpid() = 15242,pthread_self return value = 140151340103424
    i am main thread,getpid() = 15242,pthread_self return value = 140151382009600

    结论:return是函数返回,不一定是线程函数哦(情形2-2)! 只有线程函数(情形2-1)return,线程才会退出。

    情形3-1:使用pthread_exit函数退出

     1 /*************************************************************************
     2     > File Name: pthread8.c
     3     > Summary: pthread_exit函数 情形1
     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 *callBack(void *arg)
    16 {
    17     int i = (int)arg;
    18     sleep(i);
    19     if(i == 2){
    20         // 函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。函数无返回值,参数为传出参数。
    21         pthread_exit(NULL);
    22     }
    23     
    24     // pthread_self():用来获得线程id。返回值为线程id,没有参数。
    25     printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu
    ", i+1, getpid(), pthread_self());
    26     return NULL;
    27 }
    28 
    29 int main()
    30 {
    31     pthread_t pid;
    32     /*
    33     pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
    34     参数1:pthread_t tid;   传出参数,指向线程标识符的指针。      &tid
    35     参数2:属性  null
    36     参数3:回调函数的函数指针。
    37     参数4:回调函数的参数列表。没有的话传NULL
    38     */
    39     int i;
    40     for(i = 0; i<5; i++)
    41     {
    42         int ret = pthread_create(&pid,NULL,callBack, (void *)i);
    43         if(ret != 0)
    44         {
    45             printf("pthread_create fail
    ");
    46             exit(-1);
    47         }
    48     }
    49     
    50     //阻塞主线程一会
    51     sleep(i);
    52     printf("i am main thread,getpid() = %d,pthread_self return value = %lu
    ", getpid(), pthread_self());
    53     return 0;
    54 }

    运行结果:(正常)

    i am 1 th thread,getpid() = 15695,pthread_self return value = 139924312561408
    i am 2 th thread,getpid() = 15695,pthread_self return value = 139924304168704
    i am 4 th thread,getpid() = 15695,pthread_self return value = 139924287383296
    i am 5 th thread,getpid() = 15695,pthread_self return value = 139924278990592
    i am main thread,getpid() = 15695,pthread_self return value = 139924320896768

    情形3-2:使用pthread_exit函数退出(嵌套)

     1 /*************************************************************************
     2     > File Name: pthread9.c
     3     > Summary: pthread_exit函数 情形2 (嵌套)
     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 *fun()
    16 {
    17     pthread_exit(NULL);
    18 }
    19 
    20 void *callBack(void *arg)
    21 {
    22     int i = (int)arg;
    23     sleep(i);
    24     if(i == 2){
    25         // 函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。函数无返回值,参数为传出参数。
    26         //pthread_exit(NULL);
    27         fun();
    28     }
    29     
    30     // pthread_self():用来获得线程id。返回值为线程id,没有参数。
    31     printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu
    ", i+1, getpid(), pthread_self());
    32     return NULL;
    33 }
    34 
    35 int main()
    36 {
    37     pthread_t pid;
    38     /*
    39     pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
    40     参数1:pthread_t tid;   传出参数,指向线程标识符的指针。      &tid
    41     参数2:属性  null
    42     参数3:回调函数的函数指针。
    43     参数4:回调函数的参数列表。没有的话传NULL
    44     */
    45     int i;
    46     for(i = 0; i<5; i++)
    47     {
    48         int ret = pthread_create(&pid,NULL,callBack, (void *)i);
    49         if(ret != 0)
    50         {
    51             printf("pthread_create fail
    ");
    52             exit(-1);
    53         }
    54     }
    55     
    56     //阻塞主线程一会
    57     sleep(i);
    58     printf("i am main thread,getpid() = %d,pthread_self return value = %lu
    ", getpid(), pthread_self());
    59     return 0;
    60 }

    运行结果:(正常)

    i am 1 th thread,getpid() = 15902,pthread_self return value = 140551462266624
    i am 2 th thread,getpid() = 15902,pthread_self return value = 140551453873920
    i am 4 th thread,getpid() = 15902,pthread_self return value = 140551437088512
    i am 5 th thread,getpid() = 15902,pthread_self return value = 140551428695808
    i am main thread,getpid() = 15902,pthread_self return value = 140551470601984

    pthread_exit()用于线程退出,可以指定返回值,以便其他线程通过pthread_join()函数获取该线程的返回值。

    情形4:主函数中使用pthread_exit替代sleep:

     1 /*************************************************************************
     2     > File Name: pthread10.c
     3     > Summary: pthread_create() 循环创建多个线程   主函数中使用pthread_exit替代sleep
     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 *callBack(void *arg)
    16 {
    17     int i = (int)arg;
    18     sleep(i);
    19     // pthread_self():用来获得线程id。返回值为线程id,没有参数。
    20     printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu
    ", i+1, getpid(), pthread_self());
    21     return NULL;
    22 }
    23 
    24 int main()
    25 {
    26     pthread_t pid;
    27     /*
    28     pthread_create():成功返回值0,失败返回一个错误号(非0的值)。
    29     参数1:pthread_t tid;   传出参数,指向线程标识符的指针。      &tid
    30     参数2:属性  null
    31     参数3:回调函数的函数指针。
    32     参数4:回调函数的参数列表。没有的话传NULL
    33     */
    34     int i;
    35     for(i = 0; i<5; i++)
    36     {
    37         int ret = pthread_create(&pid,NULL,callBack, (void *)i);
    38         if(ret != 0)
    39         {
    40             printf("pthread_create fail
    ");
    41             exit(-1);
    42         }
    43     }
    44     
    45     //阻塞主线程一会
    46     //sleep(i);
    47     printf("i am main thread,getpid() = %d,pthread_self return value = %lu
    ", getpid(), pthread_self());
    48     // 这里使用pthread_exit替换sleep()
    49     pthread_exit(NULL);
    50     return 0;                                // 主函数中使用return退出,相当于使用exit函数
    51 }

    运行结果:

    i am main thread,getpid() = 16149,pthread_self return value = 140101106128640
    i am 1 th thread,getpid() = 16149,pthread_self return value = 140101097793280
    i am 2 th thread,getpid() = 16149,pthread_self return value = 140101089400576
    i am 3 th thread,getpid() = 16149,pthread_self return value = 140101081007872
    i am 4 th thread,getpid() = 16149,pthread_self return value = 140101072615168
    i am 5 th thread,getpid() = 16149,pthread_self return value = 140101064222464
  • 相关阅读:
    Microsoft Excel 不能使用对象链接和嵌入的错误/cannot use object linking and enbedding
    (转)QML代码与现有Qt UI代码整合
    vs2012编译Qwt
    参数和返回类型也可以多态
    多态的运行
    调用哪个方法
    继承的意义
    设计继承树2
    设计继承树1
    了解继承
  • 原文地址:https://www.cnblogs.com/xuelisheng/p/10114929.html
Copyright © 2011-2022 走看看