操作系统实验三:【进程控制】

简介: 进程控制

实验三:进程控制

红体字依然是懒懒的小白必看内容~~

803020b7e8ad478f9c20c1eff218d0d6.jpg

【实验前的准备】

先来点**必读材料**

一、进程的控制


进程因创建而存在,因执行完成或异常原因而终止.在进程的生命周期中,进程在内存中有三种基本状态:**就绪,执行,阻塞**.进程状态的转换是通过进程控制原语来实现的。Linux操作系统提供了相应功能的系统调用及命令,来实现用户层的进程控制。

二、相关命令:


(1)睡眠指定时间

执行格式:# sleep x,x为指定睡眠的秒数。

(2)结束或终止进程 kill

执行格式: # kill [-9] PID (PID为利用ps命令所查出的process ID)

(3)查看正在background中执行的process

执行格式:# jobs

(4)用户在终端输入Linux命令时,对应的shell通常会建立子进程来运行该命令。通过ps命令可以查看用户空间的当前进程。

执行格式: # ps [-auf]

-a 列出当前终端上启动的所有进程;

-u 按用户名和启动时间的顺序来显示进程;

-f 以全格式列出

三、系统调用:


1、exec( )系列:

如果exec( )调用成功,调用进程将被覆盖,然后从新程序的入口开始执行。exec( )没有建立一个与调用进程并发的子进程,而是用**新进程取代了原来进程**。所以exec( )调用成功后,没有任何数据返回。

2、exec( )和fork( )联合使用

系统调用exec和fork( )联合使用能为程序开发提供有力支持。用fork( )建立子进程,然后在子进程中使用exec( ),这样就实现了父进程与一个与它完全不同子进程的并发执行。


更多关于exec()系列函数,请见这位大佬的博文:

https://blog.csdn.net/amoscykl/article/details/80354052?utm_source=app&app_version=5.3.0&code=app_1562916241&uLinkId=usr1mkqgl919blen

3、wait()

等待子进程运行结束。如果子进程没有完成,父进程一直等待。

4、sleep()

睡眠指定时间。该函数使得当前进程自我阻塞second秒,由执行态转换成阻塞态,直到系统唤醒。

5、exit()

终止进程的执行。为了及时回收进程所占用的资源并减少父进程的干预,LINUX/LINUX利用exit( )来实现进程的自我终止,通常父进程在创建子进程时,应在进程的末尾安排一条exit( ),使子进程自我终止。exit(0)表示进程正常终止,exit(1)表示进程运行有错,异常终止。


掌握了以上知识点,就可以开始实验了~


【实验目的】

1、了解进程创建后对进程控制的系统调用,可实现对进程的有效控制

2、掌握进程的睡眠、同步、撤消等进程控制方法


【实验内容】

0、阅读实验相关资料。

1、通过相关命令,对进程的状态进行控制。

2、编写程序,使用fork( )创建一个子进程。使用相关的系统调用控制进程的状态。观察并分析多进程的执行次序及状态转换。


【实验步骤】:

1、参考程序:

#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
int main( )
{      
  int pid;    
  pid=fork( );        /*创建子进程*/
  switch(pid) 
  {
           case  -1:                          /*创建失败*/
    printf("fork fail!\n");
    exit(1); 
       case  0:/*子进程*/
    printf("Is son:\n"); 
    execl("/bin/ls","ls","-l",NULL); 
    printf("exec fail!\n");
    exit(1);
       default:/*父进程*/
    printf("ls parent:\n");
    while(1)  sleep(1);
    exit(0);
      }
  return 0;
}

2、运行结果:

yzy@yzy-virtual-machine:~/123$ gcc fork_exec.c -o def
yzy@yzy-virtual-machine:~/123$ ./def&
[2] 2318
yzy@yzy-virtual-machine:~/123$ ls parent:
Is son:
总用量 24
-rwxrwxr-x 1 yzy yzy 16992  4月  3 10:12 def
-rw-rw-r-- 1 yzy yzy   502  4月  3 10:09 fork_exec.c

3、解释:子进程用exec( )装入命令ls,exec( )后,子进程的代码被ls的代码取代,这时子进程的PC指向ls的第1条语句,开始执行ls的命令代码。

4、用 jobs命令查看后台运行的process 。

yzy@yzy-virtual-machine:~/123$ jobs
[1]+  运行中               ./def &

5、用ps 命令显示当前终端上启动的所有进程

yzy@yzy-virtual-machine:~/123$ ps -af
UID          PID    PPID  C STIME TTY          TIME CMD
yzy         1612    1609  1 10:08 tty2     00:00:11 /usr/lib/xorg/Xorg vt2 -disp
yzy         1626    1609  0 10:08 tty2     00:00:00 /usr/libexec/gnome-session-b
yzy         2422    2416  0 10:18 pts/0    00:00:00 ./def
yzy         2423    2422  0 10:18 pts/0    00:00:00 [ls] <defunct>
yzy         2425    2416  0 10:20 pts/0    00:00:00 ps -af

解释:倒数第二行,[ls] defunct 说明进程”ls”是一个僵死进程。父进程创建一个子进程后,可以用wait()等待回收其子进程的资源,也可以正常终止后由系统回收其子进程的资源。

6、用kill命令直接杀死该子进程。

yzy@yzy-virtual-machine:~/123$ kill -9 2423
yzy@yzy-virtual-machine:~/123$ ps -af
UID          PID    PPID  C STIME TTY          TIME CMD
yzy         1612    1609  1 10:08 tty2     00:00:12 /usr/lib/xorg/Xorg vt2 -disp
yzy         1626    1609  0 10:08 tty2     00:00:00 /usr/libexec/gnome-session-b
yzy         2422    2416  0 10:18 pts/0    00:00:00 ./def
yzy         2423    2422  0 10:18 pts/0    00:00:00 [ls] <defunct>
yzy         2442    2416  0 10:25 pts/0    00:00:00 ps -af

解释:未能成功,因为父进程还没结束

7、kill命令杀死父进程之后,成功。

yzy@yzy-virtual-machine:~/123$ kill -9 2422
yzy@yzy-virtual-machine:~/123$ ps -af
UID          PID    PPID  C STIME TTY          TIME CMD
yzy         1612    1609  1 10:08 tty2     00:00:13 /usr/lib/xorg/Xorg vt2 -disp
yzy         1626    1609  0 10:08 tty2     00:00:00 /usr/libexec/gnome-session-b
yzy         2459    2416  0 10:27 pts/0    00:00:00 ps -af
[1]+  已杀死               ./def

解释:但是如果父子进程都异常终止,则shell进程将回收其资源。Init进程回收所有僵死进程资源。

8、修改程序fork_ececl.c,在父进程执行” while(1)”之前,添加代码”wait(0);”。在后台执行该程序。显示当前终端上启动的所有进程。

yzy@yzy-virtual-machine:~/123$ Is son:
总用量 24
-rwxrwxr-x 1 yzy yzy 17032  4月  3 11:03 def
-rw-rw-r-- 1 yzy yzy   530  4月  3 11:03 fork_exec.c
ls parent:

解释:子进程结束后,它的父进程在等待(调用wait函数)它,所以Is son先显示。Wait函数:若未找到处于“僵死状态”的子进程,则调用进程便在可被中断的优先级上睡眠,等待其子进程发来软中断信号时被唤醒。


9、修改以上程序,在子进程执行”printf(“Is son:\n”);”之前添加代码“sleep(1);”。(若父进程先输出,则在父进程执行printf(“ls parent:\n”);之前添加代码“sleep(1);”)观察多进程的执行序列,解释原因。

yzy@yzy-virtual-machine:~/123$ ls parent:
Is son:
总用量 24
-rwxrwxr-x 1 yzy yzy 16992  4月  3 11:16 def
-rw-rw-r-- 1 yzy yzy   531  4月  3 11:16 fork_exec.c

解释:sleep函数:second为指定睡眠的秒数。该函数使得当前进程自我阻塞second秒,由执行态转换成阻塞态,直到系统唤醒。

多次执行,都为上述结果,屏幕输出is parent后,停顿约1秒后才显示后续内容。


【实验感想】:

(1)可执行文件加载时进行了哪些处理?参考程序中,什么时候执行语句”printf(“exec fail!\n”);”?


经过这些处理:C源程序一>编译预处理一>编译一>优化程序一>汇编程序一>链接程序一>可执行文件。

execl("/bin/ls",“ls”,"-l",NULL);在这个语句中,“bin/ls”为文件目录路径;“ls”、“-l”代表执行文件传递过去的参数;Null为结束符。。如果exec( )调用成功,调用进程将被覆盖,然后从新程序的入口开始执行。

若execl()没有调用成功,失败原因记录在error中,执行下一条语句:printf("exec fail!\n")


(2)实验指导中的第5步,wait( )是如何实现进程同步的?


首先,程序在调用fork()那里创建了一个子进程后,马上调用wait(),使父进程在子进程调用之前一直处于睡眠状态,这样就使子进程先运行,子进程运行exec()装入命令后,然后调用wait(0),使子进程和父进程并发执行,实现进程同步。


(3)实验指导中的第6步,sleep(1)为什么能导致进程切换?


Sleep函数使得当前进程自我阻塞1秒,由执行态转换成阻塞态,所以从正在运行的进程中收回处理器,让等待运行的就绪态的进程来占有处理器运行。等中断处理完后,再继续恢复原进程处理


7c20e7d1449345b7b1e189368cb367d5.jpg

喜欢的朋友可以留下你的赞哦~~~



相关文章
|
1月前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
83 1
|
2月前
|
算法 调度 Python
深入理解操作系统中的进程调度算法
在操作系统中,进程调度是核心任务之一,它决定了哪个进程将获得CPU的使用权。本文通过浅显易懂的语言和生动的比喻,带领读者了解进程调度算法的重要性及其工作原理,同时提供代码示例帮助理解。
|
1月前
|
调度 开发者 Python
深入浅出操作系统:进程与线程的奥秘
在数字世界的底层,操作系统扮演着不可或缺的角色。它如同一位高效的管家,协调和控制着计算机硬件与软件资源。本文将拨开迷雾,深入探索操作系统中两个核心概念——进程与线程。我们将从它们的诞生谈起,逐步剖析它们的本质、区别以及如何影响我们日常使用的应用程序性能。通过简单的比喻,我们将理解这些看似抽象的概念,并学会如何在编程实践中高效利用进程与线程。准备好跟随我一起,揭开操作系统的神秘面纱,让我们的代码运行得更加流畅吧!
|
2月前
|
算法
数据结构实验之操作系统打印机管理器问题
本实验旨在通过实现操作系统中的打印机管理器问题,掌握队列的基本操作如入队、出队等,利用队列的先进先出特性解决先申请先打印的问题。实验包括队列的初始化、入队、出队、打印队列内容等功能,并通过菜单式界面进行交互。实验结果显示基本功能可正常执行,但在连续操作时存在执行失败的情况,需进一步优化。
56 4
|
12天前
|
监控 搜索推荐 开发工具
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
|
1月前
|
C语言 开发者 内存技术
探索操作系统核心:从进程管理到内存分配
本文将深入探讨操作系统的两大核心功能——进程管理和内存分配。通过直观的代码示例,我们将了解如何在操作系统中实现这些基本功能,以及它们如何影响系统性能和稳定性。文章旨在为读者提供一个清晰的操作系统内部工作机制视角,同时强调理解和掌握这些概念对于任何软件开发人员的重要性。
|
1月前
|
Linux 调度 C语言
深入理解操作系统:从进程管理到内存优化
本文旨在为读者提供一次深入浅出的操作系统之旅,从进程管理的基本概念出发,逐步探索到内存管理的高级技巧。我们将通过实际代码示例,揭示操作系统如何高效地调度和优化资源,确保系统稳定运行。无论你是初学者还是有一定基础的开发者,这篇文章都将为你打开一扇了解操作系统深层工作原理的大门。
|
1月前
|
存储 算法 调度
深入理解操作系统:进程调度的奥秘
在数字世界的心脏跳动着的是操作系统,它如同一个无形的指挥官,协调着每一个程序和进程。本文将揭开操作系统中进程调度的神秘面纱,带你领略时间片轮转、优先级调度等策略背后的智慧。从理论到实践,我们将一起探索如何通过代码示例来模拟简单的进程调度,从而更深刻地理解这一核心机制。准备好跟随我的步伐,一起走进操作系统的世界吧!
|
1月前
|
算法 调度 开发者
深入理解操作系统:进程与线程的管理
在数字世界的复杂编织中,操作系统如同一位精明的指挥家,协调着每一个音符的奏响。本篇文章将带领读者穿越操作系统的幕后,探索进程与线程管理的奥秘。从进程的诞生到线程的舞蹈,我们将一起见证这场微观世界的华丽变奏。通过深入浅出的解释和生动的比喻,本文旨在揭示操作系统如何高效地处理多任务,确保系统的稳定性和效率。让我们一起跟随代码的步伐,走进操作系统的内心世界。
|
1月前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####

热门文章

最新文章