运行的程序是一个进程。从这个进程出发,可以创建另一个进程。这两个进程之间存在着父子关系。这可以通过一个名为fork()
的库函数来实现。fork()
函数将运行中的进程分成两个进程,现有的进程被称为父进程,新的进程被称为子进程。下面是一个演示的程序:
#include <sys/types.h>
#include<stdio.h>
#include <unistd.h>
// Driver code
int main()
{
printf ("Before Forkingn");
fork();
printf ("After Forkingn");
}
运行结果:
Before Forking
After Forking
Before Forking
After Forking
说明:fork()
之后的所有语句都执行两次:
- 一次由父进程。
- 子进程第二次执行语句。
让我们更详细地讨论以下概念:
- 进程
- 父进程
- 子进程
进程
进程是正在执行的程序,即活动程序。一个过程不仅仅是程序代码,它包括以下内容:
- 程序计数器。
- 进程堆栈。
- 寄存器。
- 程序代码等
相反,程序代码只是一个文本部分。
进程在执行时会更改其状态。新状态部分取决于进程的当前活动。进程在执行期间的不同状态为:
- 新增功能
- 准备
- 运行
- 封锁
- 终止。
过程控制块和过程表与每个过程相关联。它包含有关该过程的以下重要信息:
- 进程状态。
- 进程编号。
- 程序计数器。
- 文件和寄存器列表。
- CPU 信息。
- 内存信息等
父进程
当进程执行 fork()
系统调用时,所有进程都是创建的,启动进程除外。执行 fork()
系统调用的进程是父进程。父进程是使用 fork()
系统调用创建子进程的进程。父进程可能有多个子进程,但子进程只有一个父进程。
关于 fork()
系统调用的成功:
- 子进程的进程 ID (PID) 将返回到父进程。
- 0 返回到子进程。
在fork()
系统调用失败时,
- -1 返回到父进程。
- 不会创建子进程。
子进程
子进程由操作系统中的父进程使用 fork()
系统调用创建。子进程也可以称为子进程或子任务。
- 子进程创建为其父进程的副本。
- 子进程继承其大部分属性。
- 如果子进程没有父进程,则子进程由内核直接创建。
- 如果子进程退出或中断,则会向父进程发送 SIGCHLD 信号,以通知子进程的终止或退出。
为什么需要创建一个子进程?
有时,一个程序需要同时执行多个功能。由于这些作业可能是相互关联的,因此无法创建两个不同的程序来执行它们。例如:假设有两个作业:将源文件的内容复制到目标文件,并显示一个动画进度条,指示文件复制正在进行中。GIF 进度条文件应继续播放,直到文件复制发生。复制过程完成后,应停止播放 GIF 进度条文件。由于这两个工作是相互关联的,因此它们不能在两个不同的程序中执行。此外,它们不能一个接一个地执行。这两个作业应同时执行。
此时,fork()
用于创建一个子进程,然后以这样的方式编写程序,即文件复制由父进程完成,动画 GIF 文件的显示由子进程完成。
程序1:这里的任务是展示如何同时执行两个不同但相互关联的工作。因此,跳过了文件复制和播放动画GIF文件的实际代码,仅显示了同时执行2个作业的方法。
// C program for the above approach
#include <sys/types.h>
// Driver Code
int main( )
{
int pid;
pid = fork();
if (pid == 0)
{
printf ("In child processn");
/* code to play animated GIF file */
}else
{
printf ("In parent processn");
/* code to copy file */
}
}
解释:fork()
创建了一个子进程,并将父进程的代码复制到子进程中。此后,fork()函数的执行在两个进程中继续进行。因此,fork()内部的复制代码被执行一次,而它内部的剩余代码在父进程和子进程中都被执行。因此,控制会从fork()中返回两次,尽管它实际上只被调用一次。当控制从父进程的fork()返回时,会返回子进程的PID,而当控制从子进程的fork()返回时,总是返回0。这可以被程序利用来隔离我们想在父进程中执行的代码和我们想在子进程中执行的代码。这一逻辑在上述程序中使用if
语句实现。在子进程的情况下执行 “if块”,在父进程的情况下执行 “else块”。
程序2:
这个程序将使用fork()
调用来创建一个子进程。在子进程中,我们将打印子进程和其父进程的PID,而在父进程中,我们将打印父进程和其子进程的PID。
// C program to implement
// the above approach
# include <sys/types.h>
// Driver code
int main()
{
int pid;
pid = fork();
if (pid == 0)
{
printf ("Child : I am the child processn");
printf ("Child : Child’s PID: %dn", getpid());
printf ("Child : Parent’s PID: %dn", getppid());
}else
{
printf ("Parent : I am the parent processn");
printf ("Parent : Parent’s PID: %dn", getpid());
printf ("Parent : Child’s PID: %dn", pid);
}
}
运行结果:
Child : I am the child process
Child : Child's PID: 4706
Child : Parent's PID: 4705
Parent : I am the Parent process
Parent : Parent's PID: 4705
Parent : Child's PID: 4706
在计算机科学中,进程是当前正在执行的程序的实例。它是现代操作系统中的一个基本概念,旨在允许多个进程同时运行。每个进程都有自己的内存空间、程序代码和数据,并通过进程间通信 (IPC) 机制与其他进程通信。
在流程管理的上下文中,父流程是创建一个或多个子流程的进程。父进程还可以控制和监视其子进程的执行。创建新进程时,该进程称为子进程,它从其父进程继承某些属性,例如其环境变量和打开的文件描述符。
父进程和子进程之间的关系有时称为“父子”关系。子进程也可以成为父进程并创建自己的子进程,从而创建进程层次结构。
总结一下:
- 进程是当前正在执行的程序的实例。
- 父进程是创建一个或多个子进程的进程。
- 子进程是由父进程创建的新进程,并从其父进程继承某些属性。
- 总之,进程、父进程和子进程是现代操作系统中的基本概念,它们使
- 并发执行多个程序,并允许进程的分层组织。
在现代操作系统中使用父进程和子进程的优点包括:
- 并发:通过允许多个进程并发运行,系统可以更好地利用可用资源,例如 CPU 时间、内存和磁盘 I/O。
- 隔离:每个进程都有自己的内存空间、程序代码和数据,这提供了一定程度的隔离和保护,与系统中的其他进程隔离。
- 容错:如果子进程失败,父进程可以检测到故障并采取适当的操作,例如重新启动子进程或终止程序。
- 模块化:通过将程序分解为更小的独立进程,可以更轻松地分别修改、维护和测试每个进程。
但是,使用父进程和子进程也有一些缺点:
- 开销:创建和管理多个进程需要额外的系统资源,例如内存、CPU 时间和磁盘 I/O,这可能会降低系统速度。
- 通信开销:进程间通信 (IPC) 可能是一项复杂且耗时的任务,尤其是在需要在进程之间传输大量数据时。
- 同步:进程之间的协调可能很困难,需要仔细设计以避免死锁和争用条件等问题。
- 复杂性:设计和调试使用多个进程的程序可能比设计单线程程序更复杂,并且可能需要额外的技能和专业知识。
- 总体而言,使用父进程和子进程的好处通常大于缺点,尤其是在需要高级别并发性、容错性和模块化的系统中。
进程、父进程和子进程的区别
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果。
转载请注明:文章转载自 有区别网 [http://www.vsdiffer.com]
本文标题:进程、父进程和子进程的区别
本文链接:https://www.vsdiffer.com/vs/difference-between-process-parent-process-and-child-process.html
免责声明:以上内容仅代表 个人看法、理解、学习笔记、总结和研究收藏。不保证其正确性,因使用而带来的风险与本站无关!如本网站内容冒犯了您的权益,请联系站长,邮箱: ,我们核实并会尽快处理。