Linux进程的创建

 Linux进程的创建

【实验目的】

(1)熟悉在c语言源程序中使用linux所提供的系统调用界面的方法。

(2)理解由系统调用创建的子进程的特点。

(3)掌握linux中子进程的创建方法以及调度执行情况,理解进程与程序的区别。

(4)掌握linux提供的c编译器gcc的使用方法。

(5)掌握vi的使用方法。

【实验原理/实验基础知识】

  • 由系统调用创建的子进程特点:

① 子进程复制了父进程的数据与堆栈空间,继承父进程的用户代码、组代码、环境变量等等。

② 父子映像有各自的存储空间。

③ 对于父子进程的调度执行具有随机性。

  • Linux中相关系统调用
  1. fork()
  1. 功能:创建子进程。
  2. 格式:  int  fork( )
  3. 返回值:为0时表示创建成功,从子进程返回;大于0时表示创建成功,从父进程返回,其值为子进程的PID号;等于-1时表示创建失败。
  1. getpid()
  1. 功能:获取当前进程ID号。
  2. 格式:  int  getpid ( )
  3. 返回值:当前进程ID号。
  1. getppid()
  1. 功能:获取当前进程父进程的ID号。
  2. 格式:  int  getppid ( )
  3. 返回值:当前进程父进程的ID号。
  1. wait()系统调用
  1. 功能:等待任意一个子进程终止
  2. 格式:pid_t  wait(  )
  3. 返回值:返回值≥0 表示有子进程终止,其值为终止子进程的pid号;返回值=-1 表示无子进程终止。该进程阻塞,插入等待子进程终止的队列,当有子进程终止时被唤醒。
  4. 例:wait(0)等待任意子进程结束。
  5. 注意:等待多个子进程终止需要使用多个wait(),如果该进程没有创建自己的子进程就不能使用wait()。
  6. 所用头文件:# include < sys / wait.h >,# include < sys / types.h >
  1. exit()系统调用
  1. 功能:终止进程,释放其所占有的资源,向父进程发终止信号。
  2. 格式:void  exit(status)
  3. 参数:status发送给父进程的值,0-255之间。
  4. 例:exit(0) 进程正常终止。
  5. 返回值:无返回值
  6. 头文件: # include < stdlib.h >
  • Vi的使用方法

1.vi的基本概念

vi可以分为两种模式,分别是命令模式、插入模式和底行模式,各模式的功能区分如下:

1) 命令行模式

这是进入vi的默认模式,主要功能是控制屏幕光标的移动,字符、字或行的删除,区段复制。

    2) 插入模式

  主要功能是完成数据、文字的输入,按「ESC」键从插入模式回到命令行模式。 

    3) 底行模式

  主要功能是设置命令,例如保存文件或退出vi等,按「ESC」键从插入模式回到底行模式。

    2.vi的基本操作

1)进入vi

    在系统提示符号输入vi及文件名称后,就可以进入vi默认命令行模式。

2)切换至插入模式编辑文件

  进入vi后,按键盘字母i键就可以进入插入模式输入文字或数据。

3)文本修改

  在插入模式下只能一直输入文字,如果需要修改输入的文字,则按键盘ESC键返回命令行模式再使用上下键移动光标,再删除文字。

4)退出vi及保存文件

  按键盘ESC键从插入模式回到命令行模式,输入冒号进入底行模式,继续输入命令。保存及退出相关命令:

: w filename (将文章以指定的文件名filename保存)。

: wq (存盘并退出vi) 。

: q! (不存盘强制退出vi) 。

3、命令行模式功能键

1). 删除文字

x:每按一次,删除光标所在位置的"后面"一个字符。

dd:删除光标所在行。

2). 复制

yw: 将光标所在之处到字尾的字符复制到缓冲区中。

#yw:复制#个字到缓冲区,例如单击6yw表示复制6个字。

yy: 复制光标所在行到缓冲区。

p:  将缓冲区内的字符贴到光标所在位置。所有与"y"有关的复制命令都必须与"p"配合才能完成复制与粘贴功能。

3).撤销上一次操作

撤销前一个操作按u,按多次u可以执行多次撤销。

  • GCC

1.GCC简介

GCC(GNU Compiler Collection,GNU编译器套装),是一套由 GNU 开发的编程语言编译器,能够编译C、C++等语言编写的程序。

使用GCC由C语言源代码文件生成可执行文件的过程经历四个步骤:预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和链接(Linking)。

预编译。GCC调用预处理器将预处理指令如#include包含的文件内容插入程序代码中,并做语法检查。

编译。这个阶段,GCC调用编译器将预处理后的文件进行编译,生成一个汇编语言文件。

汇编。GCC调用汇编器as处理汇编文件,并生成一个以.O为扩展名的目标文件。

链接。GCC调用链接器ld将程序中用到的函数库连同目标文件连接,产生一个可执行文件。

  1. GCC的使用

1)Linux下GCC使用的格式命令

gcc [参数] 源文件 目标文件

参数:

-o file:编译产生的文件以指定文件名保存。若没有指定文件名,则默认文件名为a.out。

-i:在GCCd头文件搜索路径中添加新目录。

-c:仅把源代码编译为目标代码,而不进行函数库链接。完成后产生一个以.O为扩展名的文件。

例:gcc test.c -o t1 表示将test.c进行编译,编译后的可执行文件名为t1。

【实验环境】VMware Workstation、RedHat

【实验步骤】

(1)父进程创建子进程

用vi编写程序,实现父进程创建一个子进程,要求j在子进程中输出当前进程为子进程的提示、当前进程的PID和父进程的PID、根据用户输入确定当前进程的返回值、退出提示信息;k在父进程中分别输出当前进程为父进程的提示、当前进程的PID和子进程的PID、等待子进程退出后获得的返回值、退出提示信息。通过gcc将程序编译链接后执行,观察并分析运行结果。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
    pid_t pid = fork();
    if (pid < 0) {
        // fork 失败
        perror("Fork failed");
        return 1;
    } else if (pid == 0) {
        // 子进程
        printf("Child process:\n");
        printf("PID: %d\n", getpid());
        printf("Parent PID: %d\n", getppid());
        // 获取用户输入确定当前进程的返回值
        int childReturnValue;
        printf("Enter return value for child process: ");
        scanf("%d", &childReturnValue);
        // 退出提示信息
        printf("Child process exiting with value: %d\n", childReturnValue);
        exit(childReturnValue);
    } else {
        // 父进程
        printf("Parent process:\n");
        printf("PID: %d\n", getpid());
        printf("Child PID: %d\n", pid);
        // 等待子进程退出,并获取其返回值
        int status;
        waitpid(pid, &status, 0);
        if (WIFEXITED(status)) {
            // 子进程正常退出
            printf("Child process exited with value: %d\n", WEXITSTATUS(status));
        } else {
            // 子进程异常退出
            printf("Child process exited abnormally\n");
        }
        // 退出提示信息
        printf("Parent process exiting\n");
    }
    return 0;
}

(2)进程家族树

用vi编写程序,在程序中连续使用4个fork(),不使用if进行返回值的判断,在最后一个fork()后输出字符“A”。通过gcc将程序编译链接后执行,观察并分析运行结果。

【实验报告】  

填写《信息技术学院学生上机实验报告》。

【思考题】

  1. 该程序的执行顺序有什么特征?

父进程先创建子进程,然后输出提示信息和相关PID信息,等待子进程退出后输出子进程的返回值。子进程输出提示信息和相关PID信息,根据用户输入确定返回值,然后退出。实现父子进程时程序相互分离,父子进程双方感受不到对方的行为。

  1. 程序中连续使用4个fork()后,其进程家族树如何?

  • 29
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不好>﹏<程序有虫子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值