使用两个子进程完成两个文件的拷贝,子进程1拷贝前一半内容,子进程2拷贝后一半内容,父进程用于回收两个子进程的资源
代码
#include
#include
#include
#include
#include
#include
int main(int argc, const char *argv[])
{
char buf[100]="";//搬运工
FILE *src=fopen("src.txt","r");//只读打开
if(src==NULL)
{
perror("fopen error R");
return -1;
}
FILE *dst=fopen("dst.txt","a");//追加写
if(dst==NULL)
{
perror("fopen error A");
return -1;
}
fseek(src,0,SEEK_END);//光标文件结尾
int num=ftell(src);//计数
fseek(src,0,SEEK_SET);//光标文件开头
//定义一个存储进程号的变量
int pid1 = -1;
//创建子进程1
pid1 = fork();
if(pid1 > 0)
{
//定义变量存储第二个进程的pid
int pid2 = -1;
pid2 = fork();
if(pid2 > 0)
{
printf("我是父进程,我的第一个子进程pid:%d,第二个为:%d\n", pid1, pid2);
//回收子进程的资源
wait(NULL);
wait(NULL);
}else if(pid2 == 0)
{
dst=fopen("dst.txt","a");
printf("我是第二个子进程\n");
bzero(buf,sizeof(buf));//把buf清空
fseek(src,0,SEEK_SET);//光标定位文件开头
fread(buf,sizeof(buf[0]),num/2,src);//读进buf
fwrite(buf,sizeof(buf[0]),num/2,dst);//写入
fclose(src);
fclose(dst);
//退出进程
exit(EXIT_SUCCESS);
}else
{
perror("fork error");
return -1;
}
}else if(pid1 == 0)
{
dst=fopen("dst.txt","a");
printf("我是第一个子进程\n");
bzero(buf,sizeof(buf));//把buf清空
fseek(src,num/2,SEEK_SET);//光标定位文件中间
fread(buf,sizeof(buf[0]),num-num/2,src);//读进buf
fwrite(buf,sizeof(buf[0]),num-num/2,dst);//写入
fclose(src);
fclose(dst);
//退出进程
exit(EXIT_SUCCESS);
}else
{
perror("fork error");
return -1;
}
return 0;
}
运行效果:
面试题
标准IO和文件IO的区别
标准IO指使用库函数实现,将内核提供的IO函数接口进行了再次封装,以提高效率
文件IO指使用系统调用,内核提供的函数,每次进行IO操作,进程都会从用户空间向内核空间进行一次切换
区别:标准IO = 文件IO + 缓冲区
关于文件描述字符:
使用原则:最小未分配原则
文件描述符,是使用open函数后,打开的一个用于对指定文件进行操作的一个整数
文件IO而言,由于直接进行系统调用,所以,依赖的就是文件描述符进行对文件操作
当一个进程启动后,系统会默认打开三个文件描述符分别是0,1,2分别对应标准输入文件描述符,标准输出文件描述符,标准输入文件描述符
什么是进程?
进程是资源分配的最小单位,系统会给每个进程分配4G的虚拟内存,其中0--3G是用户空间,3--4G是内核空间
多个进程在运行时,调度原则:时间片轮询,上下文切换
进程是动态的,有进程的创建、就绪、运行、阻塞、消亡等待,有一定的生命周期
思维导图: