实验五: 进程的创建
实验目的
1、加深对进程概念的理解,尤其是进程的动态性、并发性。
2、了解进程如何被创建。
3、使用进程管理命令。
4、了解系统调用fork()功能和实现过程;
实验内容
(1) 熟悉进程的概念,以及进程的创建,调度的基本过程。
(2) 熟悉系统调用fork()的功能
(3)编写一段程序,使用系统调用fork()创建一个子进程,并在fork()系统调用后加入代码,使子进程显示”I am the child”和进程号,而父进程显示“I am the father”和进程号。
(4)编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。试观察记录屏幕上的显示结果,并分析原因。
准备知识:
1、fork( ) 创建一个新进程。
系统调用格式:
pid=fork( )
参数定义:
int fork( )
fork( )返回值意义如下:
0:在子进程中,pid变量保存的fork( )返回值为0,表示当前进程是子进程。
>0:在父进程中,pid变量保存的fork( )返回值为子进程的id值。
-1:创建失败。
如果fork( )调用成功,它向父进程返回子进程的PID,并向子进程返回0,即fork( )被调用了一次,但返回了两次。
2、进程标识
进程都有一个ID,系统调用getpid可以得到进程的ID,而getppid可以得到父进程(创建调用该函数进程的进程)的ID.
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
参考代码:
1.
#include <stdlib.h>
#include<unistd.h>
#include<stdio.h>
int main(){
pid_t pid;
pid_t myid;
pid=fork();
if(pid<0)
{
printf("create error\n");
return -1;
}
if(pid > 0)
{
printf("this is father\n");
myid=getpid();
printf("father's id is %ld\n",myid);
}else
{
printf("this is child\n");
myid=getpid();
printf("child's id is %ld\n",myid);
}
}
运行结果:
[user@localhost ~]$ gcc fork.c -o fork
[user@localhost ~]$ ./fork
this is child
child's id is 2630
this if father
father's id is 2629
2.
#include <stdio.h>
main( )
{
int p1,p2;
while((p1=fork( ))= = -1); /*创建子进程p1*/
if (p1= =0) putchar('b');
else
{
while((p2=fork( ))= = -1); /*创建子进程p2*/
if(p2= =0) putchar('c');
else putchar('a');
}
}
第一次结果bc
第二次结果ab
说明:从进程并发执行来看,上面的三个进程没有同步措施,所以父进程与子进程的输出内容会叠加在一起。输出次序带有随机性。