进程管理实验报告
级:10网工三班    学生姓名:谢昊天    学号:1215134046
实验目的和要求:
(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(3)分析进程竞争资源现象,学习解决进程互斥的方法。
(4)了解Linux系统中进程通信的基本原理。printf怎么输出字符
实验内容与分析设计:
实验内容:
(1)进程的创建
  编写一段源程序,使系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。试观察纪录屏幕上的显示结果,并分析原因。
  (2)进程的控制
  修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕出现的现象,并分析原因。
  如果在程序中使用调用lockf()来给每一个子进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。
分析:
  (1)系统是怎样创建进程的?
  (2)可执行文件加载时进行了哪些处理?
  (3)当首次调用新创建进程时,其入口在哪里?
实验步骤与调试过程:
1.进程的创建
利用Linux系统中进程通信的基本原,理编写程序,使用系统调用fork( )创建两个子进程if(p1=fork());if(p2=fork())。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b”和“c”。
2.进程的控制
修改已编写好的程序,将每个程序的输出由单个字符改为一句话,则字符串内部的字符顺序输出时不变。在程序中使用系统调用lockf()来给每个程序加锁,可以实现进程之间的互斥。但是 , 由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,输出字符串的顺序和先后随着执行的不同而发生变化。这与打印单字符的结果相同。
实验结果:
1.进程的创建运行结果 bca(有时会出现bac)
分析:从进程执行并发来看,输出bac,acb等情况都有可能。
原因:fork()创建进程所需的时间多于输出一个字符的时间,因此在主进程创建进程2的同时,进程1就输出了“b”,而进程2和主程序的输出次序是有随机性的,所以会出现上述结果
1.进程的创建运行结果
bca(有时会出现bac)
从进程执行并发来看,输出bac,acb等情况都有可能。 fork()创建进程所需的时间多于输出一个字符的时间,因此在主进程创建进程2的同时,进程1就输出了“b”,而进程2和主程序的输出次序是有随机性的,所以会出现上述结果
2.进程的管理运行结果
child….  son…  daughter… daughter…  或child  …son  …child  …son  …daughter 
由于函数printf()输出的字符串之间不会被中断,因此,字符串内部的字符顺序输出时不变。但是 , 由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,输出字符串的
顺序和先后随着执行的不同而发生变化。这与打印单字符的结果相同。
上锁后与未上锁的输出结果相同,也是随着执行时间不同,输出结果的顺序有所不同。 分析:因为上述程序执行时,不同进程之间不存在共享临界资源(其中打印机的互斥性已有由操作系统保证)问题,所以,加锁与不加锁效果相同。
疑难小结:
通过本次实验让我了解了进程的管理,通过实现进程的创建【系统通过调用fork( )函数来创建两个子进程】、进程的控制、进程的管道通信并编写一段程序,实现进程的软中断通信。系统调用lockf()来给每个程序加锁,可以实现进程之间的互斥。加深了对进程概念的理解,明确进程和程序的区别,进一步认识并发执行的实质。巩固了课本上所学到的知识。
分析:
(1)linux中创建进程是系统调用fork来复制了自己,然后如果需要的话用execl族函数来用新的程序覆盖fork的进程。
(2):可执行文件加载时首先是创建一个新进程的fork系统调用,然后用于实现进程自我终止的exit系统调用;改变进程原有代码的exec系统调用;用于将调用进程挂起并等待子进程终止的wait系统调用;获得进程标识符的getpid系统调用等处理过程。
主要算法和程序清单:
1.进程的创建
#include<stdio.h>
main()
{
int p1,p2;
    if(p1=fork())              /*子进程创建成功*/
        putchar('b');
    else
    {
        if(p2=fork())              /*子进程创建成功*/
          putchar('c');
            else putchar('a');          /*父进程执行*/
    }
}
2.进程的控制
〈程序1〉
#include<stdio.h>
main()
{
    int p1,p2,i;
    if(p1=fork())
{
        for(i=0;i<500;i++)
                printf("parent%d\n",i);
        wait(0); /* 保证在子进程终止前,父进程不会终止*/
            exit(0);
}
    else
    {
    if(p2=fork())
            {
            for(i=0;i<500;i++)
            printf("son %d\n",i);
          wait(0); /* 保证在子进程终止前,父进程不会终止*/
            exit(0); /*向父进程信号0且该进程推出*/
}
    else
            {
            for(i=0;i<500;i++) 
            printf(“grandchild %d\n",i);
            exit(0);
}
    }
}
〈程序2〉
#include<stdio.h>
main()
{
    int p1,p2,i;
    if(p1=fork())
    {
        lockf(1,1,0);
        for(i=0;i<500;i++) 
            printf("parent %d\n",i);
        lockf(1,0,0);
          wait(0); /* 保证在子进程终止前,父进程不会终止*/
          exit(0);
}
    else
    {
          if(p2=fork())
            {
            lockf(1,1,0);
            for(i=0;i<500;i++)
printf("son %d\n",i);
            lockf(1,0,0);
        wait(0); /* 保证在子进程终止前,父进程不会终止*/
            exit(0);
              }
        else
        {
        lockf(1,1,0);
            for(i=0;i<500;i++)
printf("daughter %d\n",i);
              lockf(1,0,0);
        exit(0);
        }
    }
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。