Linux 进程复制与替换

printf 函数输出问题

printf 函数并不会直接将数据输出到屏幕,而是先放到缓冲区中,只有一下三种情况满足,才会输出到屏幕。

  1. 缓冲区满
  2. 强制刷新缓冲区 fflush
  3. 程序结束时
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[],char* envp[])
{
   printf("hello");
   //fflush(stdout);
   sleep(3);
   exit(0);
}

主函数参数介绍

int main( int argc, char* argv[], char* envp[])
  1. argc 参数个数
  2. argv 参数内容
  3. envp 环境变量
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
//参数个数 参数内容 环境变量
int main(int argc, char* argv[],char* envp[])
{
 int i = 0;
 printf("argc=%d\n",argc);

 for( ;i < argc; i++ )
 {
 printf("argv[%d]=%s\n",i,argv[i]);
 }

 for( i = 0; envp[i] != NULL; i++ )
 {
 printf("envp[%d]=%s\n",i,envp[i]);
 }
 exit(0);
 }

代码执行结果:
在这里插入图片描述

复制进程 fork

fork 方法

pid_t fork(void)

函数返回类型 pid_t 实质是 int 类型,Linux 内核 2.4.0 版本的定义是
在这里插入图片描述
fork 函数会新生成一个进程,调用 fork 函数的进程为父进程,新生成的进程为子进程。在父进程中返回子进程的 pid,在子进程中返回 0失败返回-1

僵死进程及处理方法

  1. 僵死进程概念:子进程先于父进程结束,父进程没有调用 wait 获取子进程退出码。
  2. 如何处理僵死进程:父进程通过调用 wait()完成。
  3. Init 进程收养孤儿进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
int main(int argc, char* argv[],char* envp[])
{
 char * s = NULL;
 int n = 0;

 pid_t pid = fork();
 assert( pid != -1 );

 if ( pid == 0 )
 {
 s = "child";
 n = 4;
 }
 else
 {
 s = "parent";
 n = 10;
 }

 int i = 0;

 for(; i < n; i++ )
 {
 printf("pid=%d,s=%s\n",getpid(),s);
 sleep(1);
 }

 exit(0);
 }

运行结果如下图:
在这里插入图片描述
从上图中可以看到,当子进程结束后,并没有消失,仍然可以在系统中观测到,但此时子进程其实已经运行结束了,此时子进程的状态被称为僵死状态,系统把处于该类状态的进程称为僵死进程 (defunct)。如果父进程先结束,子进程最后是不会变为僵死进程的(孤儿进程,被1号进程收养)。

操作文件的系统调用

  1. 文件操作有关的系统调用
int open(const char* pathname, int flags);//用于打开一个已存在的文件
 int open(const char* pathname, int flags,mode_t mode);//用于新建一个文件,并设置访问权限

参数介绍
pathname:将要打开的文件路径和名称
flags : 打开标志,如 O_WRONLY 只写打开
O_RDONLY 只读打开
O_RDWR 读写方式打开
O_CREAT 文件不存在则创建
O_APPEND 文件末尾追加
O_TRUNC 清空文件,重新写入
mode: 权限 如:“0600”
返回值:为文件描述符

ssize_t read(int fd, void* buf, size_t count); 

参数介绍
fd 对应打开的文件描述符
buf 存放数据的空间
count 计划一次从文件中读多少字节数据
返回值:为实际读到的字节数

ssize_t write(int fd, const void* buf,size_t count); 

参数介绍:
fd 对应打开的文件描述符
buf 存放待写入的数据
count 计划一次向文件中写多少数据

int close(int fd); 

参数介绍:
fd 要关闭的文件描述符

由于 fork 创建的子进程的 PCB 是拷贝父进程的,子进程的 PCB 中的文件表指向打开文件的指针只是拷贝了父进程 PCB 中的值,所以父子进程会共享父进程 fork 之前打开的所有文件描述符。

系统调用与库函数的区别

系统调用的实现在内核中,属于内核空间,库函数的实现在函数库中,属于用户空间。

进程替换

exec 系列替换过程:pcb 使用以前的只修改,进程实体更换。注意该系列方法功能都一样,没有区别,只是参数不同。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值