僵尸进程和Linux文件操作

僵尸进程

僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源

我们都知道进程的工作原理。我们启动一个程序,开始我们的任务,然后等任务结束了,我们就停止这个进程。 进程停止后, 该进程就会从进程表中移除。你可以通过 System-Monitor 查看当前进程。 在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程。 但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程, 因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为他的父进程……

 这个程序就是子进程比父进程先结束,那么子进程就会就会进入僵尸状态,我们在后台运行程序,然后在子进程结束后ps查看当前进程,就可以看到pid为2741进入了僵尸进程

 僵尸进程的本质就是子进程率先结束,导致了父进程未获取到子进程的退出码

那么解决僵尸进程的方式也很简单,就是让子进程结束后等待父进程结束,然后获取到子进程的退出码,然后程序正常结束退出

解决问题的关键就是让父进程获取到子进程的退出码

这里使用wait()

这里看到wait的作用就是让子进程阻塞住

这里就可以用wait阻塞子进程

 

这里就可以返回子进程的退出码从而避免僵尸进程的产生

孤儿进程

写时拷贝技术

简单的来说就是就像银行的主卡和副卡,副卡可当做除了和主卡的联系外是没有任何信息的,当你用钱时即要改变余额数量时 ,银行系统把主卡的信息拷贝一份到副卡。

在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。

那么子进程的物理空间没有代码,怎么去取指令执行exec系统调用呢?

在fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,但其对应的物理空间是同一个。当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间,如果不是因为exec,内核会给子进程的数据段、堆栈段分配相应的物理空间(至此两者有各自的进程空间,互不影响),而代码段继续共享父进程的物理空间(两者的代码完全相同)。而如果是因为exec,由于两者执行的代码不同,子进程的代码段也会分配单独的物理空间。

在网上看到还有个细节问题就是,fork之后内核会通过将子进程放在队列的前面,以让子进程先执行,以免父进程执行导致写时复制,而后子进程执行exec系统调用,因无意义的复制而造成效率的下降。


Linux文件操作

对比windows中的文件操作

在windows中,我们使用open函数对一个文件进行打开

参数分别是 路径+文件名 打开模式 权限问题

那么在Linux中,文件的操作和Windows类似但不完全相同

我们可以查看open函数在Linux中使用的要求

 这是Linux中要引入文件操作的头文件

这里可以看到,open中的参数对比window中会有不同的地方 

所以我们还要关注open中的参数

其实这个和windows中的打开模式有类似的地方

那么我们就创建一个文件来看看Linux中的文件操作有什么不同于windows中的地方

根据open的使用方法,main程序运行之后就会自己创建一个a.txt文件在当前目录下

 

结果和我们预想的一样

我们创建了一个空的普通文件

那么我们要如何要往里面写入内容呢

这里使用write函数

 

 

 这样就向文件里写入了一个hello

这里我们要关注Linux中wirte和 read的使用

 

 

这里可以看到write是没有返回值的

而read是有返回值的 返回值就是read读取到的个数

在Linux中有cp命令

那么我们可不可以通过读写完成一个自己的mycp命令

 

 那么根据这个程序运行之后会在本路径下创建一个b.txt文件

然后将a.txt中的内容给到b.txt

我们用ls命令查看一下

 这样就可以实现了自己的mycp命令

我们可以将编译好的可执行程序移动到系统的命令库中

这样就可以直接以命令的方式进行执行

文件操作和进程复制结合

这里就涉及到了关于进程PCB中的一个文件信息表中

有一个关于文件的结构体中有一个计数器

在close后会回收文件的信息

那么如果我们调换 open和 fork的位置

可以观察输出结果的改变

如果先fork再open

那么父子进程都会使用close

因此输出的结果和第一次有所区别 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值