加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

实验一:进程管理

(2011-11-23 21:13:47)
标签:

进程管理

实验

操作系统

linux

it

分类: Linux

实验目的:

1加深对进程概念的理解,明确进程和程序的区别。
2进一步认识并发执行的实质。
3学习通过进程执行新的目标程序的方法。
4了解Linux 系统中进程信号处理的基本原理

实验内容:

(1)进程的创建

编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”:子进程分别显示“b”和“c”。试观察记录屏幕上显示结果,并分析原因。

 

步骤一:了解fock()函数的原理

fock()函数通过系统调用创建一个与原来进程几乎完全相同的进程,(已执行的代码不复制)。如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。fork()函数调用一次能返回两个值,在子进程中,fork()函数返回0,在父进程中,fork()函数返回新创建子进程的进程ID。如果出现错误,fork()函数返回一个负值。

 

步骤二:编写代码

#include<stdio.h>

int main()

{

int p1 ,p2 ;

while((p1=fork())==-1); 

if(p1==0)          

putchar('b');

else

{

while((p2=fork())==-1); 

if(p2==0)            

putchar('c');

else   

putchar('a');           

}

return 0;

}

步骤三:编译运行

      输出结果:bca

 

步骤四:分析原因

        while((p1=fork())==-1);这句代码用来创建第一个子进程(一般很难出现创建失败的情况),此时有了两个进程,都从下一条语句if(p1==0)开始执行。父子进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。一般来说fock()是先进入子程序执行,后执行父进程代码。fock()函数返回给子进程的p10p1是子进程的ID,因为刚创建的子进程没有子进程,所以p10),满足if语句的条件,输出’b’。回到父进程,fock()函数返回的是p1是子进程的ID,显然不等于0,所以执行else语句,此时又创建了一个新的子进程,与上述原理一样,先进入子进程,输出’c’。再回到父进程,执行else里面的语句,输出’a’。所以输出结果为bca

  理论上由于子进程可能创建失败、系统调度策略不同,导致父子进程执行顺序不一样,程序执行的结果可能出现bbcabcacbbacbcacabcba

 

(2) 进程的控制

1. 修改已编写的程序,将每个进程的输出由单个字符改为一句话,再观察程序执行是屏幕上出现的现象,并分析其原因。

 

修改实验(1)的代码如下:

#include<stdio.h>

int main()

{

int p1 ,p2 ;

while((p1=fork())==-1); 

if(p1==0)          

printf("Child1 is running!\n");

else

{

while((p2=fork())==-1); 

if(p2==0)            

printf("Child2 is running!\n");

else   

printf("Father is running!\n");         

}

return 0;

}

执行后输出结果如下:

   Child1 is running!

   Child2 is running!

   Father is running!

原因分析:与实验(1)一样的原理,只是输出内容改变了。

 

 

2.使用exec函数族使子进程执行新的目标程序。

 

exec()函数是一个调用别的已存在的程序,使之代替原来的进程的一个系统调用。它的参数就是已存在的程序的名字。

 

代码如下:

#include <stdio.h>

#include <unistd.h>

 

int main()

{

      printf("===system call execl testing ===\n");

      execlp("date","date",0);

      printf("exec error !\n");

  

      return 0;

}

 

输出结果如下:

===system call execl testing ===

1031  23:22:13  cst 2011

原因分析:

进程执行到第一个打印函数,正常执行,输出“===system call execl testing ===”。接着调用execlp();放弃主程序,转去执行名字为“date”的程序,输出日期“— 1031  23:22:13  cst 2011”,结束。

 

(3) 编写一段程序,使其实现进程的软中断通信

使用系统调用fork()创建两个子程序,再用系统调用signal()接收父进程从键盘上来的中断信号(即按Ctrl+c键);当有中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程有信号后分别输出

Child Processll is Killed by Parent!

Child Processl2 is Killed by Parent!

父进程等待两个子进程终止后,输出如下的信息后终止:

Parent process is Killed!

 

函数分析:signal(int sign,void(*  function))有两个参数,当指定的信号(sign)到来时,它跳转去执行第二个参数function指定的函数。

   Kill(pid,sig)函数可以送参数sig指定的信号给参数pid指定的进程。

   Wait()函数  一旦调用wait()函数就阻塞自己,直到出现某个子进程退出。

  

代码如下:

  #include<stdio.h>

           #include<signal.h>

           int  wait_mark;

           void waiting()

           {

                 while(wait_mark==1);

            }

          void  stop()

          {

              wait_mark=0;

           }

          int main()

          {

               int p1,p2;

               while((p1=fork())==-1);

               if(p1==0)

               {

                   wait_mark=1;

                   signal(SIGINT,SIG_IGN);

                   signal(16,stop);

                   waiting();

                   printf("Child Process11 is Killed by Parent!\n");

                   exit(0);

                }

               else

               {

                   while((p2=fork())==-1);

                   if(p2==0)

                   {

                      wait_mark=1;

                      signal(SIGINT,SIG_IGN);     

                      signal(17,stop);

                      waiting();

 

                      printf("Child Process12 is Killed by Parent!\n");

 

                      exit(0);

                    }

                   else

                   {

                      wait_mark=1;

                      signal(SIGINT,stop);

                      waiting();

                      kill(p1,16);

                      kill(p2,17);

                      wait(0);

                      wait(0);

                      printf("Parent Process is Killed!\n");

                      exit(0);

                   }

           }

}

          

 

执行结果如下:

键盘键入:Ctrl+c

输出:

   Child Process11 is Killed by Parent!

   Child Process12 is Killed by Parent!

   Parent Process is Killed!

 

原因分析:

   父进程先创建一个子进程p1,使子进程调用waiting()函数,陷入死循环;父进程接着创建另一个子进程p2,也使子进程调用waiting()函数,陷入死循环。接着父进程本身也调用waiting()函数,陷入死循环。当键盘键入Ctrl+c键时,signal(SIGINT,stop);接收到指定的信号,调用stop()函数,使wait_mark=0;使父进程跳出死循环;接着父进程调用kill()函数kill(p1,16)                      kill(p2,17),分别向进程p1p2传送信号1617 ,同时调用wait(0)函数,使自己进入阻塞状态。     子进程p1中的signal()函数接收到信号后调用stop()函数,跳出死循环,执行打印函数,输出“Child Process11 is Killed by Parent!”;同理,子进程p2输出“Child Process12 is Killed by Parent!”;此时,两个子进程都退出了,父进程不再阻塞了,执行打印函数,输出“Parent Process is Killed!”。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有