南京邮电大学操作系统实验报告一(Linux系统及进程创建)

news2024/11/15 4:41:49

文章目录

  • 一、实验目的
  • 二、实验内容
  • 三、实验步骤(附程序原码)
  • 四、运行结果及其结果分析

一、实验目的

  1. 掌握Linux 操作系统的操作和使用;
  2. 掌握Linux 下C 语言的编辑、编译、运行的全过程;
  3. 掌握进程创建系统调用的使用。

二、实验内容

  1. 熟悉Linux 运行环境。
  2. 学习UNIX/LINUX 系统的pwd, ls, cd, ps, cp, kill 等命令,查看运行结果。
  3. 掌握C 语言的编辑、编译、运行的全过程,掌握进程创建系统调用的使用。
    a) 使用vi(全屏幕编辑器)或者文本编辑器编写C 语言文件。
    b) 使用gcc(C 语言编译器)编译C 语言文件。
    c) 运行编译生成的文件。
  4. 设计一个程序,在掌握进程创建fork()系统调用的使用,在进程中创建若干子进程。在
    主进程、子进程中制定它们的运行先后关系,分析各个进程中运行情况。

三、实验步骤(附程序原码)

  1. C 语言编辑
    (1)使用附件中的文本编辑器编辑程序
    (2)编辑最简单的hello world 程序
    (3)保存为hello.c 源文件。
  2. C 语言的编译和运行
    (1)进入终端
    5
    (1)使用pwd 查看当前路径
    pwd
    (2)使用ls 查看文件hello.c。
    ls -l hello.c
    (3)使用gcc 对源文件进行编译。
    gcc hello.c
    (4)使用ls 查看生成的可执行文件a.out
    ls -l a.out
    (5)执行a.out,查看执行结果。
    ./a.out
    注意:
    (1)编译时没有使用-o 选项指定可执行文件的文件名,确实生成的可执行文件是a.out
    (2)可以使用-o 选项指定可执行文件的文件名
    gcc hello.c -o hello.out
    指定的可执行文件的文件名是hello.out
    (3)执行文件时必须显示的指明是当前文件夹下的可执行文件,也就是在a.out 前必须加
    上./。这里./表示是当前文件夹下的。
  3. 进程创建1
/*fork1.c*/
#include <stdio.h>

int main()
{
	int p1, p2, i;
	while ((p1 = fork()) == -1)
	; /*创建进程p1*/
	if(p1 == 0)
	{
		for (i = 0; i < 8; i++)
		{
			printf("daughter %d \n", i);
		}
	}
	else
	{
		while ((p2 = fork()) == -1); /*创建进程p2*/
		if (p2 == 0)
		{
			for (i = 0; i < 8; i++)
			{
			printf("son %d \n", i);
			}
		}
		else
		{
			for (i = 0; i < 8; i++)
			{
				printf("parent %d \n", i);
			}
		}
	}
}

运行结果

执行结果中打印出来的语句没有交叉,好像三个进程是顺序执行,而不是并发执行。
5. 进程创建2,增加sleep 语句使得打印结果有交叉。

/*fork2.c*/
#include <stdio.h>
int main()
	{
	int p1, p2, i;
	while ((p1 = fork()) == -1); /*创建进程p1*/
	if(p1 == 0)
	{
		for (i = 0; i < 8; i++)
		{
			printf("daughter %d \n", i);
			sleep(4);
		}
	}
	else
	{
		while ((p2 = fork()) == -1); /*创建进程p2*/
		if (p2 == 0)
		{
			for (i = 0; i < 8; i++)
			{
				printf("son %d \n", i);
				sleep(4);
			}
		}
		else
		{
			for (i = 0; i < 8; i++)
			{
			printf("parent %d \n", i);
			sleep(4);
			}
		}
	}
	return 0;
}

程序运行结果
6. 增加代码,判断以下程序的执行产生多少个进程

#include <stdio.h>
int main()
{
	fork();
	fork();
	fork();
	return 0;
}

试着使用两个系统调用
(1)获得当前的进程号getpid();
(2)获得父进程的进程号getppid();
(3)等待子进程结束wait();
(4)在创建多个进程后,执行的过程中可能会产生孤儿进程,即父进程先于子进程之前结
束。在这种情况下,系统将子进程的父进程设定为init 进程(进程号为1)。
(5)要解决孤儿进程问题,可以在父进程中增加wait 系统调用。
参考程序:

/*count2.c*/
#include <stdlib.h>
#include <stdio.h>
int main()
{
	fork();
	fork();
	fork();
	printf("Hello, world! from process id %d, it's parent id %d\n", getpid(), getppid());
	wait(0);
	wait(0);
	wait(0);
	return 0;
}

执行结果如下图所示。
可以画出这8 个进程的进程关系树。

10
root@duanwh-virtual-machine:~# ./count2.out
Hello, world! from process id 17361, it's parent id 16421
Hello, world! from process id 17362, it's parent id 17361
Hello, world! from process id 17363, it's parent id 17361
Hello, world! from process id 17364, it's parent id 17361
root@duanwh-virtual-machine:~# Hello, world! from process id 17365, it's parent id
17362
Hello, world! from process id 17366, it's parent id 17362
Hello, world! from process id 17367, it's parent id 17363
Hello, world! from process id 17368, it's parent id 17365
进程号父进程号
17361 16421
17362 17361
17363 17361
17364 17361
17365 17362
17366 17362
17367 17363
17368 17365
16421 是bash 的进程号,16421 创建了第一个进程1736117361 创建了173621736317364 三个进程;17362 进程创建了1736517366 两个进程;17363 创建了17367 一个
进程;17365 创建了17368 一个进程。
  1. 在父进程中使用fork 创建一个子进程,子进程拷贝了父进程的代码段和数据段。系统还
    提供一个vfork 也是创建一个子进程,子进程共享父进程的代码段和数据段。fork 后父
    子进程的执行次序不确定。vfork 保证子进程先运行,在调用exec 或exit 之前与父进程
    数据是共享的,在它调用exec 或exit 之后父进程才可能被调度运行。
  2. 实验总结
    a) 常用的命令行
    b) 熟悉Linux 下的C 语言编辑、编译和运行。
    c) 特殊进程
    i. 父进程
    ii. 子进程
    11
    iii. init 进程(1 号进程)
    iv. 守护进程(幽灵进程,daemon)
    v. 孤儿进程
    vi. 僵尸进程(zombie)
  3. 以下的程序执行会产生孤儿进程。
#include <stdio.h>
int main()
{
	int pid;
	pid = fork();
	if (pid == 0)
	{
		printf("child pid = %d, ppid = %d\n", getpid(), getppid());
		sleep(2);
		printf("child pid = %d, ppid = %d\n", getpid(), getppid());
	}
	else
	{
		printf("parent pid = %d, ppid = %d\n", getpid(), getppid());
	}
	return 0;
}

执行结果
执行结果分析:
(1)执行了两次,第一次是parent 先打印,第二次是child 进程先打印。两次的执行结果
不同,这个就体现了操作系统基本特性中的异步性。
(2)分析第一次执行结果。(父进程的进程号是23331,子进程的进程号是23332)
1)父进程先打印,打印结束后,父进程结束。
2)子进程打印第一次的时候已经是孤儿进程了。子进程的两次打印结果是一样的。
(3)分析第二次执行结果。(父进程的进程号是23334,子进程的进程号是23335)
1)子进程先打印第一次,此时父进程没有结束,子进程不是孤儿进程,打印出了子进
12
程的进程号和父进程的进程号。子进程执行sleep 语句进入阻塞状态。
2)父进程执行,打印自身的进程号和自己的父进程的进程号。父进程结束。
3)子进程等待时间到了后继续执行,打印第二句话,此时父进程已经结束,子进程变
成了孤儿进程。
10. 以下的程序执行会出现僵尸进程。

/*daemon.c*/
#include <stdio.h>
int main()
{
	int pid;
	pid = fork();
	if (pid > 0)
	{
		while(1)
		{
			//nothing
		}
	}
	else
	{
		printf("child pid = %d, ppid = %d\n", getpid(), getppid());
	}
	return 0;
}

另打开一个终端,使用ps -al|grep daemo 可以看到子进程是僵尸状态。
执行结果分析:
(1)涉及到两个进程,父进程的进程号23473,子进程的进程号23474。

四、运行结果及其结果分析

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/931297.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uview ui 查看版号

版本查询2种方式 有两种方式可以查询到正在使用的uView的版本&#xff1a; // 通过console.log打印的形式 console.log(uni.$u.config.v);// 可以查阅uView的配置文件得知当前版本号&#xff0c;具体位置为&#xff1a; /uview-ui/libs/config/config.js

实现文件上下文管理(__enter__和__exit__)

目录 一、上下文管理协议 二、模拟open 三、优点 python从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129328397?spm1001.2014.3001.5502 我们知道在操作文件对象的时候可以这么写 with open(a.txt) as f:代码块 上述叫做上下文管理…

Redis初始以及安装

"梦却了无影踪&#xff0c;梦仍不曾改动" 初始Redis (1) Redis是什么&#xff1f; 要认识、学习一个软件&#xff0c;最重要的途径无一是去该软件的官方文档里瞅瞅、转悠转悠。 从官方文档的介绍中得知&#xff0c;Redis是一种工作于内存&#xff0c;…

神奇小队之我爱画画

《神奇小队之我爱画画》&#xff0c;是南通神笔动漫科技有限公司2022年推出的原创系列动画剧集。 南通神笔动漫创立于2020年4月&#xff0c;公司专注于2-12岁儿童内容策划、运营文创企业。公司主要运营动漫IP《神奇画笔》&#xff0c;项目于2020年创立《神奇画笔》儿童IP&…

GBU812-ASEMI逆变器专用整流桥GBU812

编辑&#xff1a;ll GBU812-ASEMI逆变器专用整流桥GBU812 型号&#xff1a;GBU812 品牌&#xff1a;ASEMI 芯片个数&#xff1a;4 封装&#xff1a;GBU-4 恢复时间&#xff1a;&#xff1e;50ns 工作温度&#xff1a;-55C~150C 浪涌电流&#xff1a;200A 正向电流&…

【LeetCode-中等题】48. 旋转图像

文章目录 题目方法一&#xff1a;使用辅助数组矩阵 行列的规律方法二&#xff1a;原地修改 递推公式 题目 方法一&#xff1a;使用辅助数组矩阵 行列的规律 public void rotate(int[][] matrix) {int n matrix.length;int[][] matrix_new new int[n][n];for(int i 0 ; i<…

探索AIGC人工智能(Midjourney篇)(一)

文章目录 案例图片 Midjourney注册 创建Discord账号 下载客户端 添加Midjourney到自己的服务器 用Midjourney画一只会飞的鸭子 Midjourney绘画指令 Midjourney绘画指令_激发Midjourney的创造力 Midjourney绘画指令_Seed指令 Midjourney光线关键词&#xff0c;打造震撼…

深入剖析Kubernetes之容器技术概念入门篇

文章目录 进程层面隔离与限制容器镜像 容器本身没有价值&#xff0c;有价值的是“容器编排”。 也正因为如此&#xff0c;容器技术生态才爆发了一场关于“容器编排”的“战争”。而这次战争&#xff0c;最终以 Kubernetes 项目和 CNCF 社区的胜利而告终。 容器&#xff0c;到底…

Linux常用命令_网络命令、关机重启命令

文章目录 1. 网络命令1.1 网络命令: write1.2 网络命令: wall1.3 网络命令: ping1.4 网络命令: ifconfig1.5 网络命令: mail1.6 网络命令: last1.7 网络命令: lastlog1.8 网络命令: traceroute1.9 网络命令: netstat1.10 网络命令: setup1.11 挂载命令 2. 关机重启命令2.1 shut…

基于Java+SpringBoot+Vue前后端分离线上辅导班系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

移植U8g2图形库—驱动OLED显示(模拟IIC)

目录 1. 所需器件工具 2. IO端口配置 3. 移植步骤 3.1 精简c源码 3.1.1 去掉无用的驱动文件 3.1.2 精简u8g2_d_setup.c 3.1.3 精简u8g2_d_memory.c 3.2 创建函数 3.2.1 创建回调函数 3.2.2 创建测试函数 4. 添加u8g2源码到工程 4.1 项目文件配置 4.2 主函数main.c…

xsschallenge通关(11-15)

level 11 老规矩&#xff0c;先查看源码&#xff0c;做代码审计&#xff1a; <?php ini_set("display_errors", 0); $str $_GET["keyword"]; $str00 $_GET["t_sort"]; $str11$_SERVER[HTTP_REFERER]; $str22str_replace(">&quo…

[C++][C#]yolox TensorRT C++ C#部署

YOLOX是一种新型的高性能探测器&#xff0c;由开发者Zheng Ge、Songtao Liu、Feng Wang、Zeming Li和Jian Sun在《YOLOX: Exceeding YOLO Series in 2021》首次提出。与YOLOV5和YOLOV8相比&#xff0c;YOLOX具有更高的性能和更好的平衡&#xff0c;在速度和精度方面都表现出优越…

无涯教程-机器学习 - 数据统计

在进行机器学习项目时&#xff0c;通常无涯教程会忽略两个最重要的部分&#xff0c;分别是 数学 和 数据 。这是因为知道ML是一种数据驱动的方法&#xff0c;并且ML模型只会产生与提供给它的数据一样好的或坏的输出。 在上一章中&#xff0c;讨论了如何将CSV数据上传到ML项目中…

GMP原理与调度

GMP原理和调度 1.Golang"调度器"的由来1.1单进程时代不需要调度器1.2多进程/线程时代有了调度器需求1.3协程来提高cpu利用率 1.Golang"调度器"的由来 1.1单进程时代不需要调度器 早期的操作系统每个程序就是一个进程&#xff0c;直到一个程序运行完毕&am…

Leetcode81. 搜索旋转排序数组 II

已知存在一个按非降序排列的整数数组 nums &#xff0c;数组中的值不必互不相同。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转 &#xff0c;使数组变为 [nums[k], nums[k1], ..., nums[n-1], nu…

C++ 网络编程项目fastDFS分布式文件系统(七)--qss样式表,项目文件的上传和下载。

目录 1 单例模式 2. 如何在单例类中存储数据? 3. QSS样式表 3.1 选择器类型 3.2 QSS的使用步骤 3.3 登录窗口设置 4. 客户端post方式上传数据 4.1 常用的四种方式 5. 上传协议 1 单例模式 #include<iostream> #include<vector> #include<mutex> …

Python加入Excel--生产力大提高|微软的全方面办公

Python作为一种功能强大的编程语言&#xff0c;已经逐渐成为了数据分析、机器学习、Web开发等领域的主流语言之一。而将Python集成到Excel中&#xff0c;则可以为Excel用户提供更加强大的数据处理和分析能力&#xff0c;同时也可以为Python开发者提供更加便捷的数据处理和可视化…

法雷奥Valeo EDI解决方案

法雷奥集团&#xff08;Valeo&#xff09;是一家总部位于法国的专业致力于汽车零部件、系统、模块的设计、开发、生产及销售的工业集团。公司业务涉及原配套业务及售后业务&#xff0c;是世界领先的汽车零部件供应商&#xff0c;为世界上所有的主要汽车厂提供配套。作为一家高科…

UI位置与布局

UI位置与布局 引言 发现UGUI的RectTransform定位还是很复杂的&#xff0c;感觉有必要详细了解一下 RectTransform 继承自Transform。他的local position由其他几个变量控制。建议不要直接设置position 目的是为了实现UI自动布局。这套方法将绝对定位&#xff0c;相对定位&a…