【编程小实验】利用Linux fork()与文件I/O:父进程与子进程协同实现高效cp命令(前半文件与后半文件并行复制)

简介: 这个小程序是在文件IO的基础上去结合父子进程的一个使用,利用父子进程相互独立的特点实现对数据不同的操作

 目录

这个小程序是在文件IO的基础上去结合父子进程的一个使用,利用父子进程相互独立的特点实现对数据不同的操作

技术简单讲解:

创建子进程

进程ID(PID)

资源继承与共享

父子进程的独立性

子进程结束与父进程的责任

实例应用

代码思路:

源码:


这个小程序是在文件IO的基础上去结合父子进程的一个使用,利用父子进程相互独立的特点实现对数据不同的操作

技术简单讲解:

在Linux系统中,进程是执行中的程序实例,每个进程都有其独立的地址空间、资源分配和执行流。当一个进程创建了另一个进程时,前者称为父进程,后者称为子进程。这种关系通过进程间的一种特殊层次结构来体现,是操作系统管理并发执行的基础之一。以下是关于Linux下父子进程的关键概念和操作:

创建子进程

在Linux中,通常使用`fork()`系统调用来创建一个新的子进程。`fork()`调用会产生一个与父进程几乎完全相同的副本(除了进程ID和一些与进程相关的资源标识符),然后在父子进程中分别返回不同的值。在父进程中,`fork()`返回的是子进程的PID(进程ID);而在子进程中,`fork()`返回0。

进程ID(PID)

每个进程都有一个唯一的PID,用于在系统中唯一标识该进程。父进程知道子进程的PID,但反过来不一定,子进程并不直接知道其父进程的PID,但可以通过`getppid()`系统调用获取父进程的PID。

资源继承与共享

子进程继承了父进程的大部分资源,包括但不限于打开的文件描述符、信号处理函数、当前工作目录、用户ID和组ID等。但是,某些资源如内存映射区域可以被标记为“写时复制”(Copy-On-Write, COW),这意味着除非子进程或父进程尝试修改这些资源,否则它们共享同一物理内存,以节省资源。

父子进程的独立性

虽然子进程是从父进程创建的,但一旦创建完成,两者就成为相互独立的实体,各自拥有独立的执行路径、堆栈空间和变量副本。父子进程可以通过IPC(进程间通信)机制如管道、信号、共享内存等进行通信和数据交换。

子进程结束与父进程的责任

当子进程执行完毕或因其他原因终止时,它会变成僵尸状态(Zombie),此时它不再占用任何系统资源,仅保留一个很小的内核记录,包含其PID和退出状态。父进程应该通过`wait()`或`waitpid()`系统调用来收集子进程的退出状态,并释放僵尸进程。如果父进程不这样做,子进程会成为孤儿进程,最终由init进程(PID为1)接管。

实例应用

- **后台服务与前台任务分离**:父进程可以启动子进程处理耗时或后台任务,而自身继续执行其他操作。

- **并发处理**:通过创建多个子进程实现简单的并发执行,提高程序的处理能力和响应速度。

- **一次性任务**:创建子进程执行一次性或有风险的操作,即使子进程崩溃也不会影响父进程的稳定性。

理解并合理运用Linux下的父子进程机制,是编写高效、可靠多任务程序的基础。

代码思路:

利用父子进程特性实现文件分割复制

父子进程特性简介

  • 独立内存空间:父子进程拥有独立的虚拟地址空间,这意味着它们的数据段、堆、栈等都是分离的。
  • 执行顺序:父进程先于子进程执行,子进程是在父进程执行特定系统调用(如fork())后创建的。

文件分割复制策略

要实现文件的分割复制,可以利用上述父子进程特性,通过以下步骤完成:

  1. 文件预处理:使用文件I/O操作打开源文件和目标文件。
  • 开启两个文件,分别用于读取源文件和写入目标文件。
  1. 计算文件大小:读取源文件,统计其总字节数。
  • 可以通过逐字节读取直至遇到文件结束符(EOF)的方式来计算文件大小,或者更高效地使用lseek()fstat()函数。
  1. 父进程操作:复制源文件的前半部分至目标文件。
  • 计算出文件一半的字节数。
  • 使用read()write()系统调用,循环读取并写入数据,直到完成前半部分的复制。
  1. 子进程操作:复制源文件的后半部分至目标文件。
  • 在父进程中调用fork()创建子进程。
  • 子进程使用lseek()将源文件指针移动到文件中间位置。
  • 重复父进程的读写操作,完成剩余数据的复制。

源码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    // 文件IO实现cp 父进程复制前一半 子进程复制后一办
    // 1. 打开文件
    char a[1] = {0};
    int src = open(argv[1], O_RDONLY);
    if (src < 0)
    {
        perror("open error");
        return -1;
    }
    int dest = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0666);
    if (dest < 0)
    {
        perror("open error");
        return -1;
    }
    // 2. 计算读取文件的字符个数
    int size = lseek(src, 0, SEEK_END) - lseek(src, 0, SEEK_SET);
    int halfsize = size / 2;
    ssize_t s;
    // 3. 开始打印
    pid_t pid = fork();
    if (pid < 0)
    {
        perror("fork error");
        return -1;
    }
    else if (pid == 0)// 子进程
    {
        lseek(src, l, SEEK_SET);
        lseek(dest, l, SEEK_SET);
        for (int i = 0; i < halfsize; i++)
        {
            s = read(src, a, 1);
            write(dest, a, s);
        }
    }
    else// 父进程
    {
        lseek(src, 0, SEEK_SET);
        lseek(dest, 0, SEEK_SET);
        for (int i = 0; i < halfsize; i++)
        {
            s = read(src, a, 1);
            write(dest, a, s);
        }
    }
    return 0;
}

image.gif


相关文章
|
2天前
|
Linux 网络安全 开发工具
linux 常用命令【编程必备】
linux 常用命令【编程必备】
14 4
|
2天前
|
存储 Linux
Linux文件的上和下,FinalShell文件右键可下文件,先选择root文件夹,然后把他文件往里面拖动,就可以下载了,命令下载,ls -l可以看当前文件目录,sz 文件名可下载,tab补,rz出上
Linux文件的上和下,FinalShell文件右键可下文件,先选择root文件夹,然后把他文件往里面拖动,就可以下载了,命令下载,ls -l可以看当前文件目录,sz 文件名可下载,tab补,rz出上
|
2天前
|
安全 Linux 测试技术
Linux命令setpriv详解
`setpriv` 是Linux下的命令行工具,用于调整进程权限以增强安全性,尤其适用于自动化和非交互式权限切换。它不使用PAM,支持管理能力集、GID/UID及SELinux上下文。例如,`setpriv --reuid=1000 script.sh` 可以以低权限用户运行脚本,而`--selinux-label`可设定SELinux标签。在使用时,应最小化权限、充分测试、保持与其他安全机制的兼容性,并定期审核权限设置。
|
2天前
|
Linux 数据安全/隐私保护
Linux命令setfacl详解
`setfacl`是Linux中用于设置文件访问控制列表的命令,提供比传统权限更细粒度的控制。它允许为特定用户或组添加、修改或删除权限,适用于多用户环境和复杂场景。常用参数包括`-m`(修改规则)、`-x`(删除规则)、`-R`(递归设置)和`-d`(设置默认ACL)。例如,`setfacl -m u:user1:rw- file.txt`给用户`user1`赋予文件`file.txt`的读写权限。记得在使用前确认文件系统支持ACL,并谨慎规划和审查权限设置。
|
2天前
|
Linux 数据处理
Linux命令setarch深度解析与实际应用
`setarch`是Linux下用于调整程序执行环境的命令,它允许在不同CPU架构间运行二进制文件,模拟架构并设置CPU功能标志。通过指定`-a`参数切换架构,如`-a i386`,用`-R`参数启用或禁用如SSE2的功能。在测试兼容性、调试和优化时非常有用。注意正确设置参数,避免滥用,确保程序正常运行。查阅文档、逐步测试和考虑兼容性是最佳实践。
|
2天前
|
Linux
Linux部署 cd-pwd命令,cd 不写参数 就直接回到用户的HOME目录,pwd 查看当前的工作目录,pwd是常看当前目录的路径,无参数
Linux部署 cd-pwd命令,cd 不写参数 就直接回到用户的HOME目录,pwd 查看当前的工作目录,pwd是常看当前目录的路径,无参数
|
2天前
|
Linux
Linux部署04-ls命令的参数和选项,主体,参数,选项,ls / 查看根目录下的文件夹,-a的意思是列出全部选项 ls -a home全部文件,.代表着隐藏的文件夹,-l 选项,以列表竖向的形式展
Linux部署04-ls命令的参数和选项,主体,参数,选项,ls / 查看根目录下的文件夹,-a的意思是列出全部选项 ls -a home全部文件,.代表着隐藏的文件夹,-l 选项,以列表竖向的形式展
|
2天前
|
Linux
Linux02---命令基础 Linux命令基础, ls命令入门,ls命令参数和选项,命令行是一种以纯字符操作系统的方式,command命令本身,options命令的细节行为,parameter命令的
Linux02---命令基础 Linux命令基础, ls命令入门,ls命令参数和选项,命令行是一种以纯字符操作系统的方式,command命令本身,options命令的细节行为,parameter命令的
|
2月前
|
安全 网络协议 Linux
【专栏】Linux系统中ping命令的使用,包括其基本语法、输出信息、常用参数及高级用法
【4月更文挑战第28天】本文详细介绍了Linux系统中ping命令的使用,包括其基本语法、输出信息、常用参数及高级用法。通过ping,用户可测试网络连通性、诊断故障及评估性能。此外,文章还讨论了ping在不同协议、模拟网络环境及与其他命令结合使用时的场景。注意防火墙和网络环境可能影响ping结果,理解错误信息有助于网络问题排查。熟练掌握ping命令,能助你成为Linux网络专家。不断学习和实践,提升网络技能,为构建稳定网络环境贡献力量。
|
2月前
|
Kubernetes Linux Shell
Linux |奇怪的知识---complete命令---你不知道的命令参数补全---kubectl命令的参数补全
Linux |奇怪的知识---complete命令---你不知道的命令参数补全---kubectl命令的参数补全
58 0

热门文章

最新文章