操作系统实验二【进程的创建】

简介: 进程的创建(小白系列第二弹~)

前言:

在实验前,需要先了解一些基本知识~

1、fork函数

功能:***创建一个新的子进程***。其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码、组代码、环境变量、已打开的文件代码、工作目录和资源限制。注意:子进程总是从fork之后开始复制父进程的。

系统调用格式: int fork()

如果Fork调用成功,则在父进程会返回新建立的子进程标识符(PID),而在新建立的子进程中则返回0。如果fork失败则直接返回-1。

调用fork()函数需要包含头文件#include <unistd.h>


2、wait函数

功能:等待子进程运行结束。如果子进程没有完成,父进程一直等待。wait( )将调用进程挂起,直至其子进程因暂停或终止而发来软中断信号为止。如果在wait( )前已有子进程暂停或终止,则调用进程做适当处理后便返回。调用wait()函数需要包含头文件#include <sys/wait.h>

系统调用格式:int wait(status)


3、exit函数

功能:终止进程的执行。其中,status是返回给父进程的一个整数。为了及时回收进程所占用的资源并减少父进程的干预,UNIX/LINUX利用exit( )来实现进程的自我终止,通常父进程在创建子进程时,应在进程的末尾安排一条exit( )语句,使子进程自我终止。exit(0)表示进程正常终止,exit(1)表示进程运行有错,异常终止。调用exit()函数需要包含头文件:#include<stdlib.h>

系统调用格式:void exit(status)


提示:以下是本篇文章正文内容,下面案例可供参考


正文:

[实验目的]:

1、掌握进程的概念,进一步理解进程和程序的区别。

2、认识和了解并发执行的实质。

3、掌握fork()、wait()、exit()函数。


[实验内容]:

一、进程的创建:

在Linux系统,创建C文件的方法,详情请见我的第一篇博文~


进程的创建:编写一段程序,使用系统调用fork( )创建两个子进程,在系统中有一个父进程和两个子进程活动。让每个进程在屏幕上显示一个字符;父进程显示字符“f”,两个子进程分别显示字符“s” 和“d”。多次运行可执行程序,观察记录屏幕上的显示结果,并分析原因。画出进程树的结构图。

代码:

#include<stdio.h>
#include <unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
  int  main()
    { int  p1, p2,pid;
    while((p1=fork())== -1);
    printf("ok....\n");  // 创建成功为止
    if(p1==0){    //如果是子进程
          putchar('s');
          printf("  ");
          printf("i am the child1:%d   ",getpid());
          printf("the return value:%d\n",p1);
          exit(0);
       }
    else            
      { while((p2=fork())==-1);
        if(p2==0){ 
          putchar('d');
            printf("  ");
            printf("i am the child2:%d   ",getpid());
            printf("the return value:%d\n",p2);
            }
        else{
            pid=wait(0);
            putchar('f');
            printf("  ");
            printf("i am the father:%d   the return value:%d\n",getpid(),pid);      
       }
     } 
     }

结果:

yzy@yzy-virtual-machine:~/new$ ./dd.out
ok....
ok....
s  i am the child1:2830   the return value:0
d  i am the child2:2831   the return value:0
f  i am the father:2829   the return value:2830

***分析:如上图,可清晰得出进程间的关系。


由前言可知,父进程会返回新建立的子进程标识符(PID),而在新建立的子进程中则返回0。


**** OK出现两次的原因:


由前言可知,子进程总是从fork之后开始复制父进程的!!所以在第一个fork 语句后,有两个进程,一个是父进程,另一个是子进程1,去执行OK语句。


******进程树:

微信图片_20220412174044.png

二、根据进程树编写程序:

##编写程序创建进程树如图所示,在每个进程中显示当前进程标识符PID号和父进程标识符。

cb4707dcff83461d890393b22bf54ec0.png


代码:
#include<stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
int main(){
      int pid,pid2,pid3,pid4;
        pid=fork();
        if(pid<0)       
                printf("error occurred!\n");
        else if(pid==0) /* 如果是子进程 */
                {
                        printf("我是子进程b,进程号是%d\n",getpid());
                        int pid1;
                        pid1 = fork();
                        if(pid1==0){
                                printf("我是子进程b的子进程c,进程号是%d\n",getpid());
                                exit(0);
                        }
                }
        else{
                printf("我是父进程a,进程号是%d\n",getpid());
                pid4=fork();
                if(pid4==0){
                        printf("我是子进程d,进程号是%d\n",getpid());                   
                        pid2=fork();      
                        if(pid2==0){
                          printf("我是子进程d的子进程e,进程号是%d\n",getpid());
                    }
                        else{
                          pid3=fork();
                          if(pid3==0){
                          printf("我是子进程d的子进程f,进程号是%d\n",getpid());
                          exit(0);}}
                                                  }}       
        return 0;
}

结果:

yzy@yzy-virtual-machine:~/new$ ./c.out
我是父进程a,进程号是3187
我是子进程b,进程号是3188
我是子进程d,进程号是3189
我是子进程b的子进程c,进程号是3190
我是子进程d的子进程e,进程号是3191
我是子进程d的子进程f,进程号是3192

三、根据程序画进程树:

在Linux系统中运行下面的程序,最多可产生多少个进程,试画出进程家族树。

main()

{

fork();

fork();

}


代码:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/wait.h>
int main()
{int m,n,k;
m=fork();
printf("hee   ");
printf("pid:%d   ",getpid());
printf("the return value:%d\n",m);
n=fork();
printf("ha    ");
printf("pid:%d   ",getpid());
printf("the return value:%d\n",n);
}

结果:

yzy@yzy-virtual-machine:~/new$ ./hh.out
hee   pid:3312   the return value:3313
hee   pid:3313   the return value:0
ha    pid:3312   the return value:3314
ha    pid:3313   the return value:3315
ha    pid:3314   the return value:0
ha    pid:3315   the return value:0

*****进程树

微信图片_20220412174222.png

[实验感想]:

(1)系统是怎样创建进程的?

一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

(2)当首次调用新创建进程时,其入口在哪里?

fork调用成功后,子进程与父进程并发执行相同的代码。但由于子进程也继承了父进程的程序指针,所以子进程是从fork()后的语句开始执行(也就是新进程调用的入口)。fork()创建成功,返回值对子进程是0,对父进程是子进程的pid(一个正整数)。在调用fork()后,父进程和子进程均从下一条语句开始执行。另外fork在子进程和父进程中的返回值是不同的。在父进程中返回子进程的PID,而在子进程中返回0。所以可以在程序中检查PID的值,使父进程和子进程执行不同的分支。

(3)当前运行的程序(主进程)的父进程是什么?

这里调用fork创建新进程的进程即为父进程,而相对应的为其创建出的进程则为子进程,因而除了进程0以外的进程都只有一个父进程,但一个进程可以有多个子进程。


小白更新系列第二弹!喜欢的朋友可以点个赞哦~


相关文章
|
10月前
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
364 32
|
算法 调度 Python
深入理解操作系统中的进程调度算法
在操作系统中,进程调度是核心任务之一,它决定了哪个进程将获得CPU的使用权。本文通过浅显易懂的语言和生动的比喻,带领读者了解进程调度算法的重要性及其工作原理,同时提供代码示例帮助理解。
|
调度 开发者 Python
深入浅出操作系统:进程与线程的奥秘
在数字世界的底层,操作系统扮演着不可或缺的角色。它如同一位高效的管家,协调和控制着计算机硬件与软件资源。本文将拨开迷雾,深入探索操作系统中两个核心概念——进程与线程。我们将从它们的诞生谈起,逐步剖析它们的本质、区别以及如何影响我们日常使用的应用程序性能。通过简单的比喻,我们将理解这些看似抽象的概念,并学会如何在编程实践中高效利用进程与线程。准备好跟随我一起,揭开操作系统的神秘面纱,让我们的代码运行得更加流畅吧!
|
算法
数据结构实验之操作系统打印机管理器问题
本实验旨在通过实现操作系统中的打印机管理器问题,掌握队列的基本操作如入队、出队等,利用队列的先进先出特性解决先申请先打印的问题。实验包括队列的初始化、入队、出队、打印队列内容等功能,并通过菜单式界面进行交互。实验结果显示基本功能可正常执行,但在连续操作时存在执行失败的情况,需进一步优化。
176 4
|
8月前
|
缓存 运维 前端开发
|
8月前
|
缓存 运维 前端开发
阿里云操作系统控制台:高效解决性能瓶颈与抖动之进程热点追踪
遇到“进程性能瓶颈导致业务异常”等多项业务痛点时,提供高效解决方案,并展示案例。
|
11月前
|
监控 搜索推荐 开发工具
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
1251 2
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
|
C语言 开发者 内存技术
探索操作系统核心:从进程管理到内存分配
本文将深入探讨操作系统的两大核心功能——进程管理和内存分配。通过直观的代码示例,我们将了解如何在操作系统中实现这些基本功能,以及它们如何影响系统性能和稳定性。文章旨在为读者提供一个清晰的操作系统内部工作机制视角,同时强调理解和掌握这些概念对于任何软件开发人员的重要性。
|
Linux 调度 C语言
深入理解操作系统:从进程管理到内存优化
本文旨在为读者提供一次深入浅出的操作系统之旅,从进程管理的基本概念出发,逐步探索到内存管理的高级技巧。我们将通过实际代码示例,揭示操作系统如何高效地调度和优化资源,确保系统稳定运行。无论你是初学者还是有一定基础的开发者,这篇文章都将为你打开一扇了解操作系统深层工作原理的大门。
165 4

热门文章

最新文章

推荐镜像

更多