【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
原文地址:https://www.cnblogs.com/xuelisheng/p/10116182.html