进程相关知识(1)2021-09-08

注:整理源于爱编程的大丙

1、进程相关(Linux指令)

进程可以使用的资源上限
ulimit -a

查看进程 ID ,进程ID唯一
ps aux

  • a: 查看所有终端的信息
  • u: 查看用户相关的信息
  • x: 显示和终端无关的进程信息

杀死进程
kill
查看 Linux 中的标准信号
kill -l
9 号信号(SIGKILL)的行为是无条件杀死进程
kill -9 进程ID
kill -SIGKILL 进程ID(和上面那个一样)

2、进程相关(函数)

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

获取当前进程的进程 ID(PID)
pid_t getpid(void);

获取当前进程的父进程 ID(PPID)
pid_t getppid(void);

创建一个新的进程
pid_t fork(void);

3、fork

1、拷贝完成之后(注意这个时间点),两个地址空间中的用户区数据是相同的。
2、父子进程各自的虚拟地址空间是相互独立的,不会互相干扰和影响
3、每个进都有自己的进程 ID,因此内核区存储的父子进程 ID 是不同的
4、fork () 调用成功之后,会返回两个值,父子进程的返回值是不同的。
5、在程序中需要通过 fork () 的返回值来判断当前进程是子进程还是父进程。

  • 该函数调用成功之后,从一个虚拟地址空间变成了两个虚拟地址空间,每个地址空间中都会将 fork() 的返回值记录下来,这就是为什么会得到两个返回值的原因
  • 父进程的虚拟地址空间中将该返回值标记为一个大于 0 的数(其实记录的是子进程的进程 ID)
  • 子进程的虚拟地址空间中将该返回值标记 0

两个进程中是不能通过全局变量实现数据交互的,因为每个进程都有自己的地址空间,两个同名全局变量存储在不同的虚拟地址空间中,二者没有任何关联性。如果要进行进程间通信需要使用:管道,共享内存,本地套接字,内存映射区,消息队列等方式。

4、在进程中执行其它可执行程序

  • 在项目开发过程中,需要通过现在运行的进程启动磁盘上的另一个可执行程序,也就是通过一个进程启动另一个进程,这种情况下我们可以使用 exec族函数
  • 一般在调用这些函数的时候都会先创建一个子进程,在子进程中调用 exec 族函数,子进程的用户区数据被替换掉开始执行新的程序中的代码逻辑,但是父进程不受任何影响仍然可以继续正常工作。

5、进程控制

进程控制主要是指进程的退出 , 进程的回收和进程的特殊状态 孤儿进程僵尸进程

结束进程
exit() 或者_exit() 函数
main 函数中直接使用 return 也可以退出进程

// 专门退出进程的函数, 在任何位置调用都可以
// 标准C库函数
#include <stdlib.h>
void exit(int status);

// Linux的系统函数
// 可以这么理解, 在linux中 exit() 函数 封装了 _exit()
#include <unistd.h>
void _exit(int status);

孤儿进程
父进程由于某种原因先退出了,子进程还在运行,这时候这个子进程就可以被称之为孤儿进程(跟现实是一样的)

  • 当检测到某一个进程变成了孤儿进程,这时候系统中就会有一个固定的进程领养这个孤儿进程(有干爹了)。如果使用 Linux 没有桌面终端,这个领养孤儿进程的进程就是 init 进程(PID=1),如果有桌面终端,这个领养孤儿进程就是桌面进程。
  • 在子进程退出的时候, 进程中的用户区可以自己释放, 但是进程内核区的pcb资源自己无法释放,必须要由父进程来释放子进程的pcb资源,孤儿进程被领养之后,这件事儿干爹就可以代劳了,这样可以避免系统资源的浪费。

僵尸进程
子进程先与父进程结束,子进程无法释放自己的 PCB 资源,需要父进程来做这个件事儿,但是如果父进程也不管,这时候子进程就变成了僵尸进程

  • 僵尸进程不能将它看成是一个正常的进程,这个进程已经死亡了,用户区资源已经被释放了,只是还占用着一些内核资源(PCB)
    ps aux 查看进程信息
    Z+ --> 这个进程是僵尸进程, defunct, 表示进程已经死亡
  • 消灭僵尸进程的方法是杀死这个僵尸进程的父进程,这样僵尸进程的资源就被系统回收了。通过 kill -9 僵尸进程PID 的方式是不能消灭僵尸进程的,这个命令只对活着的进程有效,僵尸进程已经死了,鞭尸是不能解决问题的。

进程回收
为了避免僵尸进程的产生,一般我们会在父进程中进行子进程的资源回收,回收方式有两种,
一种是阻塞方式 wait(),一种是非阻塞方式 waitpid()。

  • wait()阻塞函数,如果没有子进程退出,函数会一直阻塞等待,当检测到子进程退出了,该函数阻塞解除回收子进程资源。这个函数被调用一次,只能回收一个子进程的资源,如果有多个子进程需要资源回收,函数需要被调用多次。
    #include <sys/wait.h>
    pid_t wait(int *status);
    成功:返回被回收的子进程的进程 ID
    失败: -1
  • waitpid () 函数可以看做是 wait () 函数的升级版,通过该函数可以控制回收子进程资源的方式是阻塞还是非阻塞,另外还可以通过该函数进行精准打击,可以精确指定回收某个或者某一类或者是全部子进程资源。
    #include <sys/wait.h>
    // 这个函数可以设置阻塞, 也可以设置为非阻塞
    // 这个函数可以指定回收哪些子进程的资源
    pid_t waitpid(pid_t pid, int *status, int options);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值