操作系统之深入了解进程

接下来的实验是主要是为了让大家深入理解进程以及进程在调度执行和内存空间等方面的特点。

在实验之前我们首先要搞清楚以下几个函数和命令。注意:该实验是在Linux环境下进行的

  • fork()函数

        首先,fork()函数是一个分叉函数,一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。

        注意的是,若fork()成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记,否则,出错返回-1。

        我们在Linux使用man命令可以看具体的介绍,由于介绍内容较多,本文不一一介绍,有兴趣的下去自己了解。(此处提示一下,用man命令查看的内容是英文版的,在有些命令当中,我们还可以使用--help进行查看汉化过的内容,但是--help并不支持全部),下图展示一下。


        
  • isdigit()函数
         isdigit() 函数是 C++ 中的一个函数,若参数为阿拉伯数字0~9,则返回非0值,否则返回 NULL, 同样可以使用man命令去了解。
  • kill命令

        kill命令是Linux中的命令,用来删除执行中的程序或工作,kill可将指定的信息送至程序。主要的用法是直接kill进程的PID,或者是搭配一些信号使用,在下面的程序中会有具体实现。


接下来就是进程的具体实验了

  • 引用头文件以及声明变量及函数等
[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. #include <sys/types.h>  
  3. #include <unistd.h>  
  4. #include <signal.h>  
  5. #include <ctype.h>  
  6. #include <stdlib.h>  
  7.   
  8. #define MAX_CHILD_NUMBER 10  
  9. #define SLEEP_INTERVAL 5  
  10.   
  11. int proc_number = 0;  
  12.   
  13. void do_something();  
  • void do_something()函数
[cpp]  view plain  copy
  1. void do_something()  
  2. {  
  3.     for(;;)  
  4.     {  
  5.         printf("This is process No.%d and its pid is %d\n",proc_number,getpid());  
  6.         sleep(SLEEP_INTERVAL);  
  7.     }     
  8. }  
  • 主函数
[cpp]  view plain  copy
  1. main(int argc,char* argv[])  
  2. {  
  3.     int child_proc_number = MAX_CHILD_NUMBER; //10  
  4.     int i,ch;  
  5.     pid_t child_pid;  
  6.     pid_t pid[10] = {0};//存放子进程id  
  7.     if (argc > 1) //命令行参数第一个参数表示子进程个数  
  8.     {  
  9.         child_proc_number = atoi(argv[1]);//atoi函数的作用是将字符串转换成整型数  
  10.         child_proc_number = (child_proc_number > 10) ? 10 : child_proc_number;  
  11.         //子进程数>10的时候,child_proc_number=10,否则等于实际值  
  12.     }  
  13.     for(i = 0; i < child_proc_number; i++)  
  14.     {     
  15.         //填写代码,建立child_proc_number个子进程要执行  
  16.         //proc_number = i;进程数  
  17.         //do_something();     
  18.         //父进程把子进程的id保存到pid[i]  
  19.         child_pid = fork();//分叉函数,返回值:若成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记,否则,出错返回-1  
  20.         if(child_pid == -1)  
  21.         {  
  22.             perror("创建错误\n");  
  23.             return 1;  
  24.         }  
  25.         else if(child_pid == 0)  
  26.         {  
  27.             proc_number=i;      //在子进程中,fork返回0    
  28.                     do_something();  
  29.         }  
  30.         else  
  31.         {  
  32.             pid[i] = child_pid; //在父进程中,fork返回新创建子进程的进程ID  
  33.         }  
  34.     }  
  35.     while((ch = getchar()) != 'q')  
  36.     {  
  37.         if(isdigit(ch))//判断是不是数字,是返回true,不是返回false  
  38.         {  
  39.             //填写  
  40.             /* 向pid[ch-'0']发信号SIGTERM,   
  41.                 * 杀死该子进程   
  42.                     */   
  43.             kill(pid[ch-'0'], SIGTERM);  
  44.         }  
  45.     }  
  46.     //填写,杀死所有进程  
  47.     kill(0, SIGKILL);   
  48.     return ;  
  49. }  

然后我们开始编译并且运行该程序

  • gcc test_2.c命令,这样默认输出a.out。我们也可以用-o指定输出文件的文件名 ,这里我使用的是gcc test_2.c -o test_2

  • 这时候我们在新终端用ps aux命令看一下具体的效果。我们看到,并且发现了一个问题,程序创建了10个进程,但是我们看到的为什么是11个呢?其实这是因为原本的程序运行也是要占用进程的,最后一栏代表的是命令,第二栏代表的就是PID了。


  • 接下来我们在原终端按(0-9)数字,并且在新终端用ps aux命令继续观察,发现进程关闭,这是因为我们用kill命令杀死了进程。


  • 这时我们的实验也就做完了,可以用q杀死所有进程了。

今天的实验就到这里,如果发现错误,请立即与我联系,我们下篇见^_^!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值