Linux进程操作(上)

目录

一、进程的创建

二、进程的退出

三、进程的回收


一、进程的创建

进程也可以创建进程 ,每个进程可以有多个子进程,比如shell窗口下敲的命令都是进程,它们的父进程都是shell脚本/bin/bash

通过下面的函数获取自身和父进程的PID

getpid() 返回自身PID

getppid() 返回父进程的PI

cpp 复制代码
pid_t fork(void);

@return 创建成功返回两次值
        一次值(子进程的PID)给到父进程中
        另一次值(0)给到创建的子进程中
    	失败返回-1
  • 父进程创建子进程后,可以通过判断fork的返回值来辨别是父进程/子进程,从而让它们执行不同的内容

  • 两个进程会交替执行 (并发),子进程只执行fork之后的代码(这样也避免了自动地无限fork)

  • 父、子进程有独立地址空间,互不影响,执行的顺序由操作系统决定

  • 子进程虚拟内存的内容和父进程大部分相同,除了进程ID、父进程ID、fork返回值、进程运行时间、闹钟、未决信号集不同,同时遵循读时共享写时复制的原则节省开销

  • 父进程先结束子进程在父进程结束的一刻成为孤儿进程 ,系统防止过多孤儿进程产生,会由init进程收养 ,然后子进程变成后台进程

  • 子进程先结束父进程没有及时回收 (父进程暂停执行,阻塞等待子进程结束退出,然后获取子进程的退出状态),导致子进程变成僵尸进程

进程创建的实用场景:

一个父进程希望复制自己,使父、子进程同时执行不同代码段。这在网络编程中很常见------父进程等待客户端的服务请求,当收到请求后,父进程创建子进程来处理此请求,父进程则继续等待下一个请求,然后再创建新的子进程...( 这不就是梦寐以求的分身吗!!!)

所以可以把子进程看作是父进程希望能有人帮他做某个工作,既然帮他做这个工作,他当然有理由关心这个工作做没做完

对于子进程,他做完了工作可以看成正常退出,没做完工作则算异常退出

对于父进程,他创建完子进程也想收集子进程的退出状态,甚至可能什么都不做,就等着子进程执行完,然后获取它的退出状态,父进程才好去执行后面的任务

二、进程的退出

cpp 复制代码
void exit(int status);  //属于标准C库
void _exit(int status); //同下面一个属于系统调用
void _Exit(int status);

@param:进程的退出状态 通过status传递给父进程,如果是异常退出,则内核来产生退出状态传给父进程

这两类退出函数的区别即标准C库和系统调用的区别,标准C库函数大多有缓冲,结束进程时会刷新流(缓冲区)的内容

return和exit的区别:return用于退出当前函数,属于堆栈的返回

exit用于结束程序运行,0表示正常,1、-1表示异常,2表示找不到文件

进程退出的类型:

1.正常退出

  • main函数中调用了return
  • 进程调用了退出进程的函数
  • 进程最后一个线程返回或调用pthread_exit

2.异常退出

  • 进程调用abort函数
  • 进程收到某些信号,如某个进程while1死循环时,占据CPU大量资源,ctrl C 可以强制退出进程
  • 最后一个线程对取消请求作出响应

三、进程的回收

pid_t wait(int *status)

功能:阻塞等待任一子进程退出 ,并获取它的退出状态(不过,退出状态不是简单地由返回值得到,甚至与返回值无关)

@param: status--整型数指针,指向用来存放子进程退出状态的变量

为空时(NULL),说明父进程不关心子进程的退出状态,这种情况比较特殊,父进程不收集子进程的退出状态,子进程退出后也不会变成僵尸进程

非空时,子进程的退出状态放在了它指向的地址,但这个地址并没直接获得退出状态,还需要进一步判断,因为退出分为正常和异常

1)调用函数来判断是哪种退出,函数名被定义成了几个宏,常用的是WIFEXITED、WIFSIGNALED,前者用来判断是否正常退出,后者判断是否异常退出,如果函数的返回值为真,则代表是对应判断的退出,如 if (WIFEXITED(state) == 1)

2)调用函数来获得退出状态,正常退出、异常退出分别用WEXITSTATUS、WTERMSIG来返回对应的退出状态信息,如WEITSTATUS(state)

@return:成功则返回退出的子进程PID,失败返回-1
pid_t waitpid((pid_t pid, int *status, int options);

功能:多用于不傻等子进程退出(当然,不及时回收容易导致子进程退出后变为僵尸进程)

@param: pid

‐1 等待任一子进程 与wait等价

> 0 等待指定进程

0 等待当前进程组的任一子进程

< -1 等待指定进程组中的任一子进程,进程组ID等于pid的绝对值

status 同wait函数

options

0 阻塞等待

WNOHANG 不阻塞等待(迅速返回结果表示子进程执行阶段)可以循环不断去检测返回值

返回值 == 0表示子进程还在执行,父进程可以继续做自己的事,

返回值 > 0表示子进程执行结束,返回值变为子进程PID,后续可以通过调用WEXITSTATUS回收它

@return: 子进程退出返回PID,没执行完会返回0

相关推荐
灏瀚星空20 分钟前
从基础到实战的量化交易全流程学习:1.3 数学与统计学基础——概率与统计基础 | 基础概念
笔记·python·学习·金融·概率论
dessler23 分钟前
Kubernetes(k8s)-集群监控(Prometheus)
linux·运维·kubernetes
一夜沐白24 分钟前
Linux用户管理
linux·运维·服务器·笔记
无敌的牛34 分钟前
AVL树的介绍与学习
数据结构·学习
【0931】44 分钟前
进程控制的学习
学习·操作系统
PLUS_WAVE1 小时前
【Tools】chezmoi 跨多台不同的机器管理 dotfiles 的工具
linux·服务器·软件工程·工具·chezmoi
阿图灵1 小时前
文章记单词 | 第48篇(六级)
学习·学习方法
triticale1 小时前
《人件》第三章 正确的人
笔记
宁建利1 小时前
树莓派学习专题<11>:使用V4L2驱动获取摄像头数据--启动/停止数据流,数据捕获,缓存释放
学习
阳光宅男@李光熠1 小时前
【质量管理】TRIZ(萃智)的工程系统进化法则
笔记·学习