IO学习day4(进程)

作业:利用文件IO函数拷贝图片。要求父进程拷贝前半部分,子进程拷贝后半部分。

#include<myhead.h>
#define N 128
char buf[N] = { 0 };//初始化容器

int main(int argc, char const *argv[])
{
	pid_t pid;//创建进程
	int r_fd,w_fd,size,ret;
	char ch = '\0';

	r_fd = open(argv[1], O_RDONLY);//以只读的形式从外部传文件名打开
	if(r_fd <0)//判断打开是否成功
    {
		ERR_MSG("open");
		exit(-1);
	}

	w_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);//以写的形式打开从外部传文件名
	if(w_fd < 0)//判断打开是否成功
    {
		ERR_MSG("write");
		exit(-1);
	}

    //获取文件总大小
	size = lseek(r_fd, 0, SEEK_END);
	if(size < 0)//判断是否有内容
    {
		ERR_MSG("lseek");
		exit(-1);
	}

    
    lseek(w_fd, size-1, SEEK_SET);//从移动写文件的偏移量到文件第一位
	if(write(w_fd, &ch, 1) < 0)
    {
		ERR_MSG("write");
		exit(-1);
	}

	size /= 2;//获取文件的一半大小的内容

	//关闭文件
	close(r_fd);
	close(w_fd);

	//创建进程
	pid = fork();
	if(pid < 0)//创建失败
    {
		ERR_MSG("fork");
		exit(-1);
	}
    //子进程拷贝一半
	else if(0 == pid)//子进程
     {
		
		r_fd = open(argv[1], O_RDONLY);//以只读的形式从外部传文件名打开
		if(r_fd < 0)
        {
			ERR_MSG("open");//判断打开是否成功
            exit(-1);
         }

    	w_fd = open(argv[2], O_WRONLY);
    	if(w_fd < 0)
        {
    		ERR_MSG("write");
            exit(-1);
    	}

        //从头拷贝一半
    	lseek(r_fd,size,SEEK_SET);
    	lseek(w_fd,size,SEEK_SET);

    	while((ret = read(r_fd, buf, N)) > 0)//判断读取文件是否有内容
        {
    		write(w_fd, buf, ret);//讲读取到的内容写到文件里
    	}

    	close(r_fd);
    	close(w_fd);
	}
	else
	{
		//父进程拷贝一半
		r_fd = open(argv[1], O_RDONLY);//以只读的形式从外部传文件名打开

		if(r_fd < 0)
        {
			ERR_MSG("open");
            exit(-1);
		}

		w_fd = open(argv[2], O_WRONLY);
		if(w_fd < 0)
        {
			ERR_MSG("open");
            exit(-1);
        }

        //拷贝后一半
		while(size > 0)
        {
			if(size > N)
            {
				write(w_fd, buf, read(r_fd, buf, N));
				size -= N;
			}
            else
            {
				write(w_fd, buf, read(r_fd, buf, size));
				break;
			}
		}

		//关闭文件
		close(r_fd);
		close(w_fd);
	}

	return 0;
}

 思维导图

 进程的五态图

 

虚拟内存空间与物理内存空间的关系

映射关系。用户只能访问用户空间的虚拟地址

 进程的内存分布

 

注意:

  1. 当父进程执行fork后,会创建一个子进程。子进程用户空间中的所有资源都是从父进程拷贝过来的。

子进程不会运行当前创建它的那个fork函数,以及fork函数以上的内容。原因如下:

PC寄存器:存储的是CPU当前要运行的指令位置。CPU通过PC寄存器存储的位置去进程中取对应位置的指令。

  1. 拷贝完毕的一瞬间,父子进程的用户空间分布完全一致。即子进程用户空间中的初始资源是从父进程拷贝过来的。

但由于父子进程用户空间相互独立,所以父子进程根据CPU的调度运行各自的代码,申请各自空间内的变量,互不干扰。

  1. 父子进程映射的物理地址,根据写时拷贝原理。
    1. 当父子进程均不修改物理地址空间中的内容是,此时父子进程映射的物理地址是一致的。
    2. 若其中一个进程要修改物理地址空间中的内容是,需要申请一块新的物理地址空间给子进程映射。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值