接上节:
1.wait 本身是一个阻塞操作,谁调用它就会使调用者阻塞
2.父进程要获得子进程的退出状态
要两个进程配合操作:
子进程:
exit(退出状态值)
退出状态值 只有最低为有效,范围为[0-255]
父进程
wait(&status)
获取到退出状态值
WIFEXITED() //先判断是否为正常退出
WEXITSTATUS //获取到exit传递的退出状态值
WIFSIGNALED:发送一个信号让子进程结束
WTERMSIG(:返回让程序结束的信号代码
练习:
Pid_t waitpid(pid_t pid,int *wstatus,int options);
功能:
等待子进程状态发生改变
参数:
非阻塞调用:
总结:
1.wait和waitpid都是等待子进程状态改变
2.wait 是一种阻塞调用
3.waitpid 可以实现非阻塞调用
进程退出:
处理方式
Wait //阻塞方式 ---调用进程 一般不做额外的事
Waitpid //非阻塞的方式 ---调用进程 逻辑一般不受影响
waitpid 想要处理到子进程
必须套在循环中
1.创建 --- fork
//创建一个子进程
//创建多个子进程
//创建好之后,能区分父子进程代码的逻辑
2.执行
A.做与父进程相同的事
B.做与父进程不同的事
fork + exec //minishell
3.进程的退出
return
exit
——exit
4.两个特殊状态
孤儿进程---没有危害,不需要处理
僵尸态进程---处理
Wait
waitpid
线程
线程即轻量级的进程
2.为什么需要线程
进程的产生 ------fork
线程 ----轻量级的进程
进程 ----重量级的进程
线程在创建时需要的资源少
线程 在创建 和 调度 时空开销都比进程小
线程 成为 CPU执行的最小单元
进程 成为 资源分配的基本单元
3.线程组成
线程 :tid //thread
程序计数器 寄存器集合 3栈
4.线程与进程的关系
a.线程是存在于 进程中的
b.线程 共享了进程的资源(代码段,数据段,打开一些文件,信号等)
c.线程结束,不一定导致进程结束
5.线程的编程 //类似与进程过程
线程函数
Red hat / IBM
// ThinkPad
Red hat 实现的一套线程函数 //NPTL线程库
NPTL(NEW posix thread library)
a.线程的创建 pthread_create
线程在编译时需要加上 - lpthread
注:
1.主函数所在的执行流-----主线程
2.其他的线程 -------子线程(次线程)
主线程和子线程之间不存在父子关系
各个线程之间 地位是平等的
获得线程的tid的函数
Pthread_self() //在那个线程中调用,获得的就是那个线程的tid号
b.线程的执行
就体现在线程的 执行函数 (回调函数)上
c.线程的退出
方式1
pthread_exit
Void pthread_exit (void *retval)
功能:
结束调用的线程
参数:
retval //退出状态值 //需要传的是,退出状态值的地址
注意:
1.pthread_exit 本身表示结束线程
如果用在main函数中 表示结束主线程
主线程结束 并不表示进程
d.线程的资源回收
Int pthread_join(pthread_t thread,void **retval)
功能:
等待线程结束
参数:
返回值:
成功 0
失败 错误码
注:
线程退出时,可以带出退户状态值
但是传的是地址