面试必备:操作系统基础——进程控制

实验三:进程控制🍀🍀🍀

【实验前的准备】:🌸🌸🌸

先来点必读材料~🍀🍀🍀🍀

一、进程的控制:🌴

进程因创建而存在,因执行完成或异常原因而终止.在进程的生命周期中,进程在内存中有三种基本状态:就绪,执行,阻塞。进程状态的转换是通过进程控制原语来实现的。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( ),这样就实现了父进程与一个与它完全不同子进程的并发执行

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

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

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

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

【实验目的】:🙈🙊🙉

1、了解进程创建后对进程控制的系统调用,可实现对进程的有效控制
2、掌握进程的睡眠、同步、撤消等进程控制方法

【实验内容】:🌝🌝🌜

0、阅读实验相关资料。
1、通过相关命令,对进程的状态进行控制。
2、编写程序,使用fork( )创建一个子进程。使用相关的系统调用控制进程的状态。观察并分析多进程的执行次序及状态转换。

【实验步骤】:🌟🌟🌟🌟

1、参考程序:

#include
#include
#include
#include
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] 
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] 
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");”?🤔

1、经过这些处理:C源程序一>编译预处理一>编译一>优化程序一>汇编程序一>链接程序一>可执行文件。
2、execl("/bin/ls","ls","-l",NULL);在这个语句中,“bin/ls”为文件目录路径;“ls”、“-l”代表执行文件传递过去的参数;Null为结束符。。如果exec( )调用成功,调用进程将被覆盖,然后从新程序的入口开始执行。
3、若execl()没有调用成功,失败原因记录在error中,执行下一条语句:printf("exec fail!\n"`)

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

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

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

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

#面试题##Linux##学习路径##校招#
全部评论
😍
1 回复 分享
发布于 2022-04-21 12:44
小姐姐可以说明下哪家的面试题会问到这些知识点吗?
点赞 回复 分享
发布于 2022-04-22 17:59

相关推荐

牛客971438129号:应该是到最后offer评估阶段了,接口人告诉我先报批,报批之后定薪,最后offer评估
点赞 评论 收藏
分享
10-16 22:56
门头沟学院 C++
1234567800:歌尔今年给211开14-15k吗,我本地人连面试都不给😂
点赞 评论 收藏
分享
11-15 18:39
已编辑
西安交通大学 Java
全村最靓的仔仔:卧槽,佬啥bg呢,本也是西交么
点赞 评论 收藏
分享
评论
5
8
分享
牛客网
牛客企业服务