计算机操作系统-实验2.1 进程的创建
0 前置知识
0.1进程创建——fork ()
fork ()函数通过系统调用创建一个与原来进程几乎完全相同的进程
两个进程可以做完全相同的事,
根据初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用fork ()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
fork()的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
1)(>0)在父进程中,fork返回新创建子进程的进程ID;
2)(=0)在子进程中,fork返回0;
3)(<0)如果出现错误,fork返回一个负值;
fork ()出错可能有两种原因:
当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。
系统内存不足,这时errno的值被设置为ENOMEM。
0.2进程标识符管理
int getpid(); //取得当前进程的标识符(进程ID)。
int getppid(); //取得当前进程的父进程ID。
int getpgrp(); //取得当前进程的进程组标识符。
int getpgid(int pid); //将当前进程的进程组标识符改为当前进程的进程ID,使其成为进程组首进程,并返回这一新的进程组标识符。
0.3wait()/waitpid()函数
作用:父进程查询子进程状态
#include <sys/types.h> #include <sys/wait.h>pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
进程一旦调用了wait(),就立即阻塞自己,由wait()自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸态的子进程,wait ()就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait ()就会一直阻塞在这里,直到有一个出现为止。
wait()要与fork()配套出现,如果在使用fork()之前调用wait(),wait()的返回值则为-1,正常情况下wait()的返回值为子进程的PID
当父进程没有使用wait()函数等待已终止的子进程时,子进程就会进入一种无父进程清理自己尸体的状态,此时的子进程就是僵尸进程,不能在内核中清理尸体的情况
1实验目的
(1)加深对进程概念的理解,进一步认识并发执行的实质。
(2)掌握Linux 操作系统中进程的创建和终止操作。
(3)掌握在Linux 操作系统中创建子进程并加载新映像的操作。
2要求
编写一个C 程序,并使用系统调用fork()创建一个子进程。要求如下:
①在子进程中分别输出当前进程为子进程的提示、当前进程的PID 和父进程的PID、根据用户输入确定当前进程的返回值、退出提示等信息。
②在父进程中分别输出当前进程为父进程的提示、当前进程的PID 和子进程的PID、等待子进程退出后获得的返回值、退出提示等信息。
3代码
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include<stdlib.h>
int main()
{
pid_t pid;
pid = fork();
if(pid < 0){
printf("error in fork");
}else if(pid == 0){
printf("I am the child process,my process ID is %d\n",getpid());
printf("My parent process ID is %d\n",getppid());
int a = 0;
printf("please enter a number as the return value of the child process\n");
scanf("%d",&a);
printf("My return value is %d\n",a);
printf("The child process will exit!\n");
exit(a);
}else{
int *status;
int a = 0;
a = waitpid(pid,status,0);
printf("I am the parent process,my process ID is %d\n",getpid());
printf("My child process ID is %d\n",a);
printf("My child process return value is %d\n",WEXITSTATUS(*status));
printf("The parent process will exit!");
exit(0);
}
return 0;
}
运行结果:
I am the child process,my process ID is 28577
My parent process ID is 28576
please enter a number as the return value of the child process
456
My return value is 456
The child process will exit!
I am the parent process,my process ID is 28576
My child process ID is 28577
My child process return value is 200
The parent process will exit!