Unix环境编程-第四章进程

本文深入探讨了进程的概念,详细解析了程序与进程的区别,进程的动态内存分布,以及操作系统如何通过虚拟内存映射来管理多个进程。文章还介绍了进程创建机制,包括fork()和vfork()函数的使用,以及子进程与父进程之间的资源共享和分离策略。此外,还讨论了进程退出的各种方式,以及如何通过wait和waitpid函数正确地回收子进程资源。

进程
程序:存储在磁盘中的静态的机器指令 静态的
程序运行之后:操作系统会把程序的指令及数据加载到内存中,形成4G虚拟内存映射
进程:程序运行之后动态的内存分布 动态的
正在运行的程序

同一个程序 可以同时运行多次

多进程:重量级 独立4G的虚拟内存空间
多线程:轻量级 共享进程的内存空间 会独立的栈空间
进程 启动很多进程

进程号只是一个数字 操作系统里面 延迟重用

把一个程序启动 放到后台 执行 a.out &

僵尸进程
孤儿进程

宏观上 程序在同时运行
微观上
单CPU的操作系统不存在真正的同时运行
在某一时刻只能执行一条指令

创建进程
pid_t fork();
调用一次返回两个值
创建一个进程

父进程 返回 子进程的 进程号
子进程 返回 0
如果出错 返回 -1

4G虚拟内存
每一个进程都有0x0 – 0xffffffff 4G的独立的虚拟内存

子进程获得父进程数据段和堆栈段(包括I/O流缓冲区)的拷贝,但子进程共享父进程的代码段。

在创建子进程之前 如果申请了动态内存 那么需要在 父子进程在都释放
如果打开了文件 那么需要在 父子进程中都关闭

同一个进程打开同一个文件两次
fd file table
v-node i-node
fd file table

dup/dup2/fcntl
fd
file table v-node i-node
fd
不同的进程打开同一个文件
fd file table v-node
i-node
fd file table v-node

子进程继承父进程文件表
父进程之前打开的文件 子进程一样也打开
fd(复制一份) file table(共享) v-node i-node

int on_exit(void (*function)(int,void *),void *arg);
调用on_exit函数第二个参数 arg 其实是用来传递给 注册函数的第二个参数
void atexit(void (*function)(void));

void exit(int status);

#include <unistd.h>
void _exit (int status);
该函数有一个完全等价的标准C版本:
#include <stdlib.h>
void _Exit (int status);

kill -9 进程号
向进程发送信息9

#include <sys/types.h>
#include <sys/wait.h>

//等待任意一个子进程结束 并获取其退出状态
pid_t wait (int* status);//能够获取子进程退出的状态的低8位 向左移8个二进制位
exit(0x8888fffb);
fb00

pid_t waitpid (pid_t pid, int* status, int options);

等待子进程终止并获取其终止状态,成功返回终止子进程的PID,失败返回-1。
options
WNOHANG 非阻塞 不等待进程结束 立即返回
如果返回0 表示还有子进程没有结果
如果返回-1 表示没有子进程需要wait

l: main函数参数是列表的列表 一个个参数并排
v: main函数参数是数组的形式
e: 参数需要传递环境列表
p: 自动去指定路径下查找程序
进程管理
程序
进程

多进程

pid_t fork() 创建一个子进程
父进程返回的是子进程的进程id
子进程返回的是0

任意一个进程都能够获得自己的进程号和父进程的进程号 getpid() getppid()

ps aux | -elf

创建进程:
父子进程共享代码段
子进程会拷贝父进程的全局区、堆、栈区
子进程拷贝父进程的文件描述符表 共享文件表(内核级的)
子进程继承父进程的环境表 信号处理方式

子进程先于父进程结束,会给父进程发送一个信号SIGCHLD(17),在父进程回收子进程的资源之前,僵尸进程

父进程先于子进程先结束,子进程就变为孤儿进程,转而被init(1)进程收养

pid_t vfork()
与vfork不同之处在于:vfork的子进程并不会拷贝父进程的数据区、堆栈区 创建进程的效率比较高
子进程基本上可以用exec系列函数直接取代该进程
vfork保证先让子进程执行
exit 才能正确的退出子进程

进程的退出
从main函数返回
exit
_exit _Exit
最后一个线程返回
主线程pthread_exit

注册函数用于进程结束之前调用
void atexit(void (*function)(void))
void on_exit(void (*function)(int,void *),void *arg)

父进程可以获取子进程的退出状态
pid_t wait(int *status);
返回-1表示没有子进程可以等待的了
如果没有子进程可以结束则阻塞

pid_t waitpid(pid_t pid,int *status,int flag)
pid = 0
pid = -1
pid > 0
pid < -1
flag WNOHANG 非阻塞

exec
l: 参数以列表的形式传递
v: 参数以数组的形式传递
e: 需要传递环境列表
p: 能够不需要带路径 会去指定的路径下搜索该可执行程序

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值