linux 线程 创建线程 终止线程 连接已终止的线程 create exit join

创建子线程:
复制代码
 1 /*
 2     man pthread: 查询线程系统调用
 3     一般情况下,  main函数所在的线程称为主线程(main线程),其余创建的线程称为子线程
 4     程序中默认只有一个进程,fork()函数调用,2个进程(父子进程)
 5     程序中默认只有一个线程(主线程),pthread_create()函数调用,有2个线程(主线程和子线程) 
 6     #include <pthread.h>
 7     int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *),) void *arg);
 8         - 功能: 创建一个子线程
 9         - 参数: 
10             - thread:传出参数,线程创建成功后,子线程的线程ID被写到该变量中。
11             - attr: 设置线程的属性, 一般使用默认值,NULL
12             - start_routine: 函数指针,这个函数是子进程需要处理的逻辑代码
13             - arg: 给第三个参数使用,传参
14         - 返回值:
15             成功: 0
16             失败:返回错误号,这个错误号与之前的errno不太一样(不能使用perror())
17             获取错误号信息: char * strerror(int errnum); (man strerror)
18 */
19 /*
20     pthread是第三方的库 需要使用 gcc pthread_create.c -o create -l 
21     查看 man pthread_create文档( Compile and link with -pthread.)
22     直接使用   gcc pthread_create.c -o create -pthread
23     等同       gcc pthread_create.c -o create -lpthread
24 */
25 #include <stdio.h>
26 #include <pthread.h>
27 #include <string.h>
28 #include <unistd.h>
29 void * callback(void * arg)//子线程
30 {
31     printf("child thread...\n");
32     return NULL;
33 }
34 int main()//主线程代码
35 {
36     pthread_t tid;//线程id
37     //创建一个子线程
38     int ret = pthread_create(&tid,NULL,callback,NULL);
39     //如果要创建多个子线程 可以多次调用 pthread_create,子线程的回调函数可以一样也可以不同(另写一个)
40     if(ret != 0)
41     {
42         char * errstr = strerror(ret);
43         printf("error:%s\n",errstr);
44     }
45     for(int i = 0; i < 5; i++)//主线程  可能主线程抢占了CPU资源 执行后return 0 无法进行子线程
46     {
47         printf("%d\n",i);
48     }
49     sleep(1);
50     return 0;
51 }
复制代码

创建子线程的第四个参数是给第三个回调函数传参:

复制代码
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <string.h>
 4 #include <unistd.h>
 5 void * callback(void * arg)//子线程
 6 {
 7     printf("child thread...\n");
 8     printf("arg value: %d\n",*(int*)arg);
 9     //arg是 (void *)  传入进来的是void类型地址, 先转为int型指针地址然后解码取值
10     return NULL;
11 }
12 int main()//主线程代码
13 {
14     pthread_t tid;//线程id
15     int num = 10;
16     //创建一个子线程
17     
18     //int ret = pthread_create(&tid,NULL,callback,NULL);
19     //如果要创建多个子线程 可以多次调用 pthread_create,子线程的回调函数可以一样也可以不同(另写一个)
20     int ret = pthread_create(&tid,NULL,callback,(void * )&num);//num的地址传为 void* 指针类型
21     if(ret != 0)
22     {
23         char * errstr = strerror(ret);
24         printf("error:%s\n",errstr);
25     }
26     for(int i = 0; i < 5; i++)//主线程  可能主线程抢占了CPU资源 执行后return 0 无法进行子线程
27     {
28         printf("%d\n",i);
29     }
30     sleep(1);
31     return 0;
32 }
复制代码

终止线程:

复制代码
 1 /*
 2     void pthread_exit(void *retval);
 3         功能:终止一个线程,在那个线程中调用,就表示终止那个线程
 4         参数:
 5             - retval:需要传递一个指针,作为一个返回值,可以在pthrad_join()中获取到
 6         返回值:没有返回值
 7 
 8     pthread_t pthread_self(void);
 9         功能:获取当前的线程的线程ID
10     
11     int pthread_equal(pthread_t t1, pthread_t t2);
12         功能: 比较两个线程ID是否相等
13         不同的操作系统,pthread_t类型实现不一样,有的是无符号的长整型,有的是使用结构体实现的
14 */
15 #include <stdio.h>
16 #include <pthread.h>
17 #include <string.h>
18 void * callback(void * arg)
19 {
20     printf("child thread id : %ld\n",pthread_self());//在哪里调用,就获取那个线程的ID
21     return NULL;//相当于thred_exit(NULL);
22 }
23 int main()
24 {
25     //创建一个子线程
26     pthread_t tid;
27     int ret = pthread_create(&tid,NULL,callback,NULL);
28     if(ret != 0)// =0 调用成功
29     {
30         char * errstr = strerror(ret);
31         printf("error:%s\n",errstr);
32     }
33     //主线程
34     for(int i = 0; i < 5; i++)
35     {
36         printf("%d\n",i);
37     }
38     printf("tid = %ld, main thread id : %ld\n",tid,pthread_self());
39     //sleep(1);
40     //让主线程退出,当主线程退出时,不会影响其他正常运行的线程
41     pthread_exit(NULL);
42     printf("main thread exit\n");//打印不出来 已经退出了当前线程
43     return 0;//exit(0);
44 }
复制代码

 连接已终止的线程:pthread_join要在子线程执行完毕后才会执行,否则一直处于阻塞状态

复制代码
 1 /*
 2     任何线程都可以回收其他线程(一般是父线程回收子线程资源)
 3     int pthread_join(pthread_t thread, void ** retval);
 4         - 功能:和一个已经终止的线程进行连接
 5             回收子线程的资源
 6             这个函数是阻塞函数,调用一次只能回收一个子线程
 7             一般在主线程中使用
 8         - 参数:
 9             - thread:需要回收的子线程ID
10             - retval:接收子线程退出时的返回值
11         - 返回值:
12             0: 成功
13             非0:失败,返回错误号
14 */
15 #include <stdio.h>
16 #include <pthread.h>
17 #include <string.h>
18 #include <unistd.h>
19 void * callback(void * arg)
20 {
21     printf("child thread id : %ld\n",pthread_self());//在哪里调用,就获取那个线程的ID
22     sleep(3);//3秒阻塞后 pthread_join()执行
23     return NULL;//相当于thred_exit(NULL);
24 }
25 int main()
26 {
27     //创建一个子线程
28     pthread_t tid;
29     int ret = pthread_create(&tid,NULL,callback,NULL);
30     if(ret != 0)
31     {
32         char * errstr = strerror(ret);
33         printf("error:%s\n",errstr);
34     }
35     //主线程
36     for(int i = 0; i < 5; i++)
37     {
38         printf("%d\n",i);
39     }
40     printf("tid = %ld, main thread id : %ld\n",tid,pthread_self());
41     //主线程调用 pthread_join()回收子线程资源
42     ret = pthread_join(tid,NULL);//不需要获取返回值填入NULL
43     if(ret != 0)
44     {
45         char * errstr = strerror(ret);
46         printf("error: %s\n",errstr);
47     }
48     printf("回收子线程资源成功\n");
49     //让主线程退出,当主线程退出时,不会影响其他正常运行的线程
50     pthread_exit(NULL);
51     return 0;
52 }
复制代码

有返回值的情况:

复制代码
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <string.h>
 4 #include <unistd.h>
 5 int  value = 10;//全局变量
 6 void * callback(void * arg)
 7 {
 8     printf("child thread id : %ld\n",pthread_self());
 9     sleep(3);//3秒阻塞后 pthread_join()执行
10     //int value = 10;//局部变量 thread_retval 为随机值 不准确
11     pthread_exit((void *)& value);//去value值的地址 转化为 void* 类型 为返回值
12     //与 return (void *)&value;相同
13 }
14 int main()
15 {
16     //创建一个子线程
17     pthread_t tid;
18     int ret = pthread_create(&tid,NULL,callback,NULL);
19     if(ret != 0)
20     {
21         char * errstr = strerror(ret);
22         printf("error:%s\n",errstr);
23     }
24     //主线程
25     for(int i = 0; i < 5; i++)
26     {
27         printf("%d\n",i);
28     }
29     printf("tid = %ld, main thread id : %ld\n",tid,pthread_self());
30     //主线程调用 pthread_join()回收子线程资源
31     int * thread_retval;//线程返回值
32     ret = pthread_join(tid,(void **)&thread_retval);//不需要获取返回值填入NULL
33     if(ret != 0)
34     {
35         char * errstr = strerror(ret);
36         printf("error: %s\n",errstr);
37     }
38     printf("exit data: %d\n",*thread_retval);
39     printf("回收子线程资源成功\n");
40     //让主线程退出,当主线程退出时,不会影响其他正常运行的线程
41     pthread_exit(NULL);
42     return 0;
43 }
复制代码

posted on   廿陆  阅读(17)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示