接下来的实验是主要是为了让大家深入理解进程以及进程在调度执行和内存空间等方面的特点。
在实验之前我们首先要搞清楚以下几个函数和命令。注意:该实验是在Linux环境下进行的
- fork()函数
首先,fork()函数是一个分叉函数,一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。
注意的是,若fork()成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记,否则,出错返回-1。
我们在Linux使用man命令可以看具体的介绍,由于介绍内容较多,本文不一一介绍,有兴趣的下去自己了解。(此处提示一下,用man命令查看的内容是英文版的,在有些命令当中,我们还可以使用--help进行查看汉化过的内容,但是--help并不支持全部),下图展示一下。
- isdigit()函数
- kill命令
kill命令是Linux中的命令,用来删除执行中的程序或工作,kill可将指定的信息送至程序。主要的用法是直接kill进程的PID,或者是搭配一些信号使用,在下面的程序中会有具体实现。
接下来就是进程的具体实验了
- 引用头文件以及声明变量及函数等
- #include <stdio.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <signal.h>
- #include <ctype.h>
- #include <stdlib.h>
- #define MAX_CHILD_NUMBER 10
- #define SLEEP_INTERVAL 5
- int proc_number = 0;
- void do_something();
- void do_something()函数
- void do_something()
- {
- for(;;)
- {
- printf("This is process No.%d and its pid is %d\n",proc_number,getpid());
- sleep(SLEEP_INTERVAL);
- }
- }
- 主函数
- main(int argc,char* argv[])
- {
- int child_proc_number = MAX_CHILD_NUMBER; //10
- int i,ch;
- pid_t child_pid;
- pid_t pid[10] = {0};//存放子进程id
- if (argc > 1) //命令行参数第一个参数表示子进程个数
- {
- child_proc_number = atoi(argv[1]);//atoi函数的作用是将字符串转换成整型数
- child_proc_number = (child_proc_number > 10) ? 10 : child_proc_number;
- //子进程数>10的时候,child_proc_number=10,否则等于实际值
- }
- for(i = 0; i < child_proc_number; i++)
- {
- //填写代码,建立child_proc_number个子进程要执行
- //proc_number = i;进程数
- //do_something();
- //父进程把子进程的id保存到pid[i]
- child_pid = fork();//分叉函数,返回值:若成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记,否则,出错返回-1
- if(child_pid == -1)
- {
- perror("创建错误\n");
- return 1;
- }
- else if(child_pid == 0)
- {
- proc_number=i; //在子进程中,fork返回0
- do_something();
- }
- else
- {
- pid[i] = child_pid; //在父进程中,fork返回新创建子进程的进程ID
- }
- }
- while((ch = getchar()) != 'q')
- {
- if(isdigit(ch))//判断是不是数字,是返回true,不是返回false
- {
- //填写
- /* 向pid[ch-'0']发信号SIGTERM,
- * 杀死该子进程
- */
- kill(pid[ch-'0'], SIGTERM);
- }
- }
- //填写,杀死所有进程
- kill(0, SIGKILL);
- return ;
- }
然后我们开始编译并且运行该程序
- 用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杀死所有进程了。
今天的实验就到这里,如果发现错误,请立即与我联系,我们下篇见^_^!!!