线程回收

pthread_join函数

阻塞等待线程退出,获取线程退出状态          其作用,对应进程中 waitpid() 函数。

       int pthread_join(pthread_t thread, void **retval); 成功:0;失败:错误号

       参数:thread:线程ID (【注意】:不是指针);retval:存储线程结束状态。

       对比记忆:

              进程中:main返回值、exit参数-->int;等待子进程结束 wait 函数参数-->int *

              线程中:线程主函数返回值、pthread_exit-->void *;等待线程结束 pthread_join 函数参数-->void **

【练习】:参数 retval 非空用法。                                                                                       【pthrd_exit_join.c】

调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:

  1. 如果thread线程通过return返回,retval所指向的单元里存放的是thread线程函数的返回值。
  2. 如果thread线程被别的线程调用pthread_cancel异常终止掉,retval所指向的单元里存放的是常数PTHREAD_CANCELED。
  3. 如果thread线程是自己调用pthread_exit终止的,retval所指向的单元存放的是传给pthread_exit的参数。
  4. 如果对thread线程的终止状态不感兴趣,可以传NULL给retval参数。

 

【练习】:使用pthread_join函数将循环创建的多个子线程回收。            

/***
thread_join.c
***/
#include<stdio.h>
#include<error.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>typedef struct 
{char ch;int var;char str[64];
}exit_t;void *thrd_func(void *arg)
{pthread_exit((void *)1);
}int main()
{pthread_t tid;int ret;int *retval;printf("In main 1 : thread id = %lu, pid = %u\n",pthread_self(),getpid());ret = pthread_create(&tid,NULL,thrd_func,NULL);if(0 != ret){fprintf(stderr,"pthread_create error : %s \n",strerror(ret));exit(1);}pthread_join(tid,(void **)&retval);printf("--------------%d\n",(int)retval);pthread_exit((void*)1);
}

运行结果:

ubuntu1604@ubuntu:~/wangqinghe/linux/20190819$ ./thread_join

In main 1 : thread id = 139721544345344, pid = 12974

--------------1

/***
pthread_join_struct.c
***/
#include<stdio.h>
#include<error.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>typedef struct 
{char ch;int var;char str[64];
}exit_t;void *thrd_func(void *arg)
{exit_t *retvar = (exit_t *)malloc(sizeof(exit_t));retvar->ch = 'm';retvar->var = 200;strcpy(retvar->str,"my thread\n");pthread_exit((exit_t *)retvar);
}int main()
{pthread_t tid;int ret;exit_t *retval;printf("In main 1 : thread id = %lu, pid = %u\n",pthread_self(),getpid());ret = pthread_create(&tid,NULL,thrd_func,NULL);if(0 != ret){fprintf(stderr,"pthread_create error : %s \n",strerror(ret));exit(1);}pthread_join(tid,(void **)&retval);printf("ch = %c,var = %d,str = %s\n--------------%d\n",retval->ch,retval->var,retval->str);free(retval);pthread_exit((void*)1);
}

运行结果:

ubuntu1604@ubuntu:~/wangqinghe/linux/20190819$ ./thread_join

In main 1 : thread id = 140316487100160, pid = 13121

ch = m,var = 200,str = my thread

 

--------------202

/***
thread_join_loop.c
***/
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>int var = 100;void *tfn(void *arg)
{int i;i = (int)arg;sleep(i);if(1 == i){var = 333;printf("var = %d\n",var);return (void*)var;}else if( 3 == i){var = 888;printf("i'm %dth pthread,pthread id = %lu ,var = %d\n",i+1,pthread_self(),var);pthread_exit((void*)var);}else{printf("i'm %dth pthread,pthread id = %lu ,var = %d\n",i+1,pthread_self(),var);pthread_exit((void*)var);        }return NULL;    
}int main()
{pthread_t tid[5];int i;int *ret[5];for(i = 0; i < 5; i++){pthread_create(&tid[i],NULL,tfn,(void*)i);}for(i = 0; i < 5; i++){pthread_join(tid[i],(void**)&ret[i]);printf("-----------%d's ret = %d\n",(int)ret[i]);}printf("I'm main pthread tid = %lu var = %d\n",pthread_self(),var);sleep(i);return 0;
}

运行结果:

ubuntu1604@ubuntu:~/wangqinghe/linux/20190819$ ./thread_loop

i'm 1th pthread,pthread id = 139809124009728 ,var = 100

-----------100's ret = -645238160

var = 333

-----------333's ret = -651408960

i'm 3th pthread,pthread id = 139809107224320 ,var = 333

-----------333's ret = -659801664

i'm 4th pthread,pthread id = 139809098831616 ,var = 888

-----------888's ret = -668194368

i'm 5th pthread,pthread id = 139809090438912 ,var = 888

-----------888's ret = 0

I'm main pthread tid = 139809132349184 var = 888

 

转载于:https://www.cnblogs.com/wanghao-boke/p/11389714.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384852.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python3数字

Python3数字数据类型用于存储数值。 数据类型是不允许改变的&#xff0c;这就意味着&#xff0c;如果改变数字数据类型的值&#xff0c;将重新分配内存空间。 Python支持三种不同不同的数值类型&#xff1a; 整型&#xff08;int&#xff09;&#xff1a;通常是被称为整型或整数…

多进程服务器

注意&#xff1a;包含了“wrap.c” 和“wrap.h”文件在上篇博客中 /*** server.c ***/ #include<stdio.h> #include<string.h> #include<netinet/in.h> #include<arpa/inet.h> #include<signal.h> #include<sys/wait.h> #include<ctype…

服务器之select

select select能监听的文件描述符个数受限于FD_SETSIZE,一般为1024&#xff0c;单纯改变进程打开的文件描述符个数并不能改变select监听文件个数解决1024以下客户端时使用select是很合适的&#xff0c;但如果链接客户端过多&#xff0c;select采用的是轮询模型&#xff0c;会大…

服务器之poll

poll服务器方法采用将监听端口用数组存放起来&#xff0c;这样就不需要轮询的监听整个文件描述符了 #include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);struct pollfd {int fd; /* 文件描述符 */short events; /* 监控的事件 */short revents; …

Mysql数据库简单使用(二)

Mysql导入.sql文件 进入数据库&#xff08;要导入的数据库&#xff09;数据库中有要导入.sql文件名的数据库&#xff0c;没有则新建。source 路径文件名souce /home/robot/csql.sql 数据库文件.sql文件放在/home/robot目录下 按照时间删除数据库数据 DELETE FROM 表名 WHERE 时…

Python3集合

集合&#xff08;set&#xff09;是一个无序的不重复元素序列。 可以使用大括号{ } 或set&#xff08;&#xff09;函数来创建集合&#xff0c;注意&#xff1a;创建一个空集合必须用set(),{ }是用来创建一个空字典的。 创建格式&#xff1a; param {value01,value02,…} set(…

Python3条件判断

if语句&#xff1a; Python中if语句的一般形式如下&#xff1a; if condition_1:statement_block_1 elif condition_2:statement_block_2 else:statement_block_3 if语句关键词&#xff1a; if – elif – else 注意&#xff1a; 每个条件后面要使用冒号:使用缩进来划分语句块&…

Python3循环

Python中while语句的一般形式&#xff1a; while 判断条件: 语句 同样需要注意冒号和缩进&#xff0c;另外在Python中没有do…while循环 下面的实例计算1到100总和 ##calc.py n 100sum 0 counter 1 while counter < n:sum sum countercounter 1print("total from…

Python3迭代器和生成器

迭代器 迭代是Python最强大的功能之一&#xff0c;是访问元素集合的一种方法。 迭代器是一个可以记住遍历的位置的对象。 迭代器对象从集合的第一个元素开始访问&#xff0c;直到所有的元素被访问完结束&#xff0c;迭代器只能向前不会后退。 迭代器有两个基本方法&#xff0c;…

Pythton3实例

计算1-100之和 #add.py n 0 sum 0 for n in range(0,101):sum n print(sum) 实现99乘法法则 #mul.py i 1 while i < 9:j 1while j < i:mut j*iprint("%d * %d %d"%(j,i,mut),end" ")j 1print(" ")i 1 运算结果: robotubuntu:~/wa…

Python3函数

函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现单一&#xff0c;或相关功能的代码段。 函数能提高应用的模块性&#xff0c;和代码的重复使用率。 定义一个函数 可以定义一个由自己想要功能的函数&#xff0c;以下是简单规则&#xff1a; l 函数代码块是以def关…

epoll函数

epoll是Linux下多路复用IO接口select/poll的增强版本&#xff0c;它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率&#xff0c;因为它会复用文件描述符集合来传递结果而不用迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合&#xff0…

epoll事件模型

事件模型 EPOLL事件有两种模型&#xff1a; Edge Triggered (ET) 边缘触发只有数据到来才触发&#xff0c;不管缓存区中是否还有数据。 Level Triggered (LT) 水平触发只要有数据都会触发。 思考如下步骤&#xff1a; 假定我们已经把一个用来从管道中读取数据的文件描述符(RFD)…

epoll反应堆模型代码

libevent函数库核心思想 /*** epoll_loop.c ***/ #include<stdio.h> #include<sys/epoll.h> #include<sys/socket.h> #include<arpa/inet.h> #include<fcntl.h> #include<unistd.h> #include<errno.h> #include<string.h> #in…

UDP广播

广播是在局域网之间的一对多的通信方式&#xff0c;使用的udp协议 /*** client.c ***/ #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h>#define SERVER_PORT 8000 #define MAXLINE…

UDP组播

多播(组播) 组播组可以是永久的也可以是临时的。组播组地址中&#xff0c;有一部分由官方分配的&#xff0c;称为永久组播组。永久组播组保持不变的是它的ip地址&#xff0c;组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的&#xff0c;甚至可以为零。那些没…

Python3数据结构

列表&#xff1a; Python列表是可变的&#xff0c;这是它区别于字符串数组和元组的最重要的特点。列表可以修改&#xff0c;而字符串和元组不能。 以下是Python中列表的描述方法&#xff1a; 方法 描述 list.append(x) 将元素添加到列表结尾 list.extend(L) 通过添加指定列…

sed、awk工具

ed sed意为流编辑器&#xff08;Stream Editor&#xff09;&#xff0c;在Shell脚本和Makefile中作为过滤器使用非常普遍&#xff0c;也就是把前一个程序的输出引入sed的输入&#xff0c;经过一系列编辑命令转换为另一种格式输出。sed和vi都源于早期UNIX的ed工具&#xff0c;所…

C语言正则表达式

POSIX规定了正则表达式的C语言库函数&#xff0c;详见regex(3)。我们已经学习了很多C语言库函数的用法&#xff0c;读者应该具备自己看懂man手册的能力了。本章介绍了正则表达式在grep、sed、awk中的用法&#xff0c;学习要能够举一反三&#xff0c;请读者根据regex(3)自己总结…

makefile通用版本

实际当中程序文件比较大&#xff0c;这时候对文件进行分类&#xff0c;分为头文件、源文件、目标文件、可执行文件。也就是说通常将文件按照文件类型放在不同的目录当中&#xff0c;这个时候的Makefile需要统一管理这些文件&#xff0c;将生产的目标文件放在目标目录下&#xf…