【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\n");
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\n", 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\n");
41             exit(-1);
42         }
43     }
44     
45     //阻塞主线程一会
46     sleep(i);
47     printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", 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\n", 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\n");
45             exit(-1);
46         }
47     }
48     
49     //阻塞主线程一会
50     sleep(i);
51     printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", 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\n", var);
21     return NULL;
22 }
23 
24 int main()
25 {
26     printf("before child thread create var = %d\n", 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\n");        
39         exit(-1);
40     }
41     //阻塞主线程一会
42     sleep(1);
43     printf("after child thread over now var = %d\n", 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\n", 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\n");
45             exit(-1);
46         }
47     }
48     
49     //阻塞主线程一会
50     sleep(i);
51     printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", 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\n", 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\n");
45             exit(-1);
46         }
47     }
48     
49     //阻塞主线程一会
50     sleep(i);
51     printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", 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\n", 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\n");
49             exit(-1);
50         }
51     }
52     
53     //阻塞主线程一会
54     sleep(i);
55     printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", 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\n", 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\n");
46             exit(-1);
47         }
48     }
49     
50     //阻塞主线程一会
51     sleep(i);
52     printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", 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\n", 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\n");
52             exit(-1);
53         }
54     }
55     
56     //阻塞主线程一会
57     sleep(i);
58     printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", 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\n", 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\n");
41             exit(-1);
42         }
43     }
44     
45     //阻塞主线程一会
46     //sleep(i);
47     printf("i am main thread,getpid() = %d,pthread_self return value = %lu\n", 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

猜你喜欢

转载自www.cnblogs.com/xuelisheng/p/10114929.html