知识点链接
https://www.yuque.com/aihenaobaijin/camuoq/lscmvf6z1arklau4?singleDoc# 《IO进程》
建议先学习知识点,再进行下面的练习
练习1: 通过父子进程完成对文件的拷贝(cp)
通过父子进程完成对文件的拷贝(cp),父进程从文件开始到文件的一半开始拷贝,子进程从文件的一半到文件末尾。要求:文件IO cp src dest
(1) 文件长度获取:lseek
(2) 子进程定位到文件一半:lseek
(3) 父进程怎么准确读到文件一半的位置?
(4) fork之前打开文件,父子进程读写时,位置指针是同一个
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char const *argv[])
{
int fd1, fd2;
pid_t pid;
char buf[32];
ssize_t n;
if (argc != 3)
{
printf("err: %s <srcfile> <destfile>\n", argv[0]);
return -1;
}
fd1 = open(argv[1], O_RDONLY);
if (fd1 < 0)
{
perror("fd1 err");
return -1;
}
fd2 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0777);
if (fd2 < 0)
{
perror("fd2 err");
return -1;
}
//获取源文件长度的一半
off_t len = lseek(fd1, 0, 2) / 2;
//创建子进程
pid = fork();
if (pid < 0)
{
perror("fork err");
return -1;
}
else if (pid == 0) //拷贝后半段
{
//定位到一半的位置
lseek(fd1, len, 0);
lseek(fd2, len, 0);
//读源文件,写入目标文件
while ((n = read(fd1, buf, 32)) > 0)
{
write(fd2, buf, n);
sleep(1);
}
}
else //拷贝前半段
{
wait(NULL); //等子进程读写完父进程再拷贝
//定位到文件开头
lseek(fd1, 0, 0);
lseek(fd2, 0, 0);
//读源文件,写入目标文件
while (len > 0)
{
if (len > 32)
n = read(fd1, buf, 32);
else
n = read(fd1, buf, len);
write(fd2, buf, n);
len -= n; //len保存的是剩余要读的字符个数
sleep(1);
}
}
close(fd1);
close(fd2);
return 0;
}
练习2:创建一个守护进程,循环间隔1s向文件中写入一串字符“hello”
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
pid_t pid;
pid = fork();
if (pid < 0)
{
perror("fork error");
return -1;
}
if (pid == 0)
{
int fd;
fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0777);
if (fd < 0)
{
perror("open error");
return -1;
}
setsid();
chdir("/");
umask(0);
for (int i = 0; i < 3; i++)
{
close(i);
}
while (write(fd, "hello\n", 6))
{
sleep(1);
}
}
else
{
exit(0);
}
return 0;
}