操作系统实验报告

时间:2024.4.20

操作系统实验报告

实验三、进程通信(一)
        
——管道及共享内存

一、         实验目的

1)            加深对管道通信的了解

2)            掌握利用管道进行通信的程序设计

3)            了解共享内存通信的程序设计方法

4)            了解和熟悉Linux支持的共享存储区机制

二、         实验内容

任务一、

(1)阅读以上父子进程利用管道进行通信的例子(例1),写出程序的运行结果并分析。

(2)编写程序:父进程利用管道将一字符串交给子进程处理。子进程读字符串,将里面的字符反向后再交给父进程,父进程最后读取并打印反向的字符串。

任务二、

(1)阅读例2的程序,运行一次该程序,然后用ipcs命令查看系统中共享存储区的情况,再次执行该程序,再用ipcs命令查看系统中共享内存的情况,对两次的结果进行比较,并分析原因。最后用ipcrm命令删除自己建立的共享存储区。 (有关ipcs和ipcrm介绍见后面一页)

(2)每个同学登陆两个窗口,先在一个窗口中运行例3程序1(或者只登陆一个窗口,先在该窗口中以后台方式运行程序1),然后在另一个窗口中运行例3程序2,观察程序的运行结果并分析。运行结束后可以用ctrl+c结束程序1的运行。

(3)编写程序:使用系统调用shmget(),shmat(),shmdt(),shmctl(),编制程序。要求在父进程中生成一个30字节长的私有共享内存段。接下来,设置一个指向共享内存段的字符指针,将一串大写字母写入到该指针指向的存贮区。调用fork()生成子进程,让子进程显示共享内存段中的内容。接着,将大写字母改成小写,子进程修改共享内存中的内容。之后,子进程将脱接共享内存段并退出。父进程在睡眠5秒后,在此显示共享内存段中的内容(此时已经是小写字母)。

三、         代码及运行结果分析

(1)      阅读以上父子进程利用管道进行通信的例子(例1),写出程序的运行结果并分析

实验代码:

#include<stdio.h>

main()

{   int x,fd[2];

    char buf[30],s[30];

    pipe(fd);

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

    if (x==0)

    {

       close(fd[0]);

       printf("Child Process!\n");

       strcpy(buf,"This is an example\n");

       write(fd[1],buf,30);

       exit(0);

    }

    else{

       close(fd[1]);

       printf("Parent Process!\n");

       read(fd[0],s,30);

       printf("%s\n",s);

   }

}

运行结果:

分析:

调用pipe(fd);创建一个管道后,接着调用fork()函数产生两个进程,首先开始执行子进程,关闭管道出口,通过管道入口向管道中写入内容。执行if语句后,进入else语句块内开始父进程,管道入口关闭,通过管道出口端从管道中读取之前写入内容,最后输出出来

(2)      编写程序:父进程利用管道将一字符串交给子进程处理。子进程读字符串,将里面的字符反向后再交给父进程,父进程最后读取并打印反向的字符串。

实验代码:

#include<stdio.h>

main()

{   int x,count,left,right,temp,fd[2],fe[2];

    char c,buf[30],s[30];

    pipe(fd);

    pipe(fe);

    printf("please input a line of char");

    scanf("%s",buf);

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

    if(x==0)

    {

       close(fd[0]);

      close(fe[1]);

       printf("Child Process!\n");

       write(fd[1],buf,30);

       read(fe[0],buf,30);

       printf("%s\n",buf);

       exit(0);

    }

    else{

       close(fd[1]);

      close(fe[0]);

      count=0;

do

{read(fd[0],&c,1);

s[count++]=c;

}while(c!='\0');

printf("Parent Process!\n");

printf("%s\n",s);

count-=2;

for(left=0,right=count;left<=count/2;left++,right--){

temp=s[left];

s[left]=s[right];

s[right]=temp;

}

      write(fe[1],s,30);

wait(0);

   }

}

运行结果:

(3)      阅读例2的程序,运行一次该程序,然后用ipcs命令查看系统中共享存储区的情况,再次执行该程序,再用ipcs命令查看系统中共享内存的情况,对两次的结果进行比较,并分析原因。最后用ipcrm命令删除自己建立的共享存储区。 (有关ipcs和ipcrm介绍见后面一页)

实验代码:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

main()

{

key_t key=208; /*在实际实验过程中,为了避免每个同学建立的共享存储区关键字一样而相互干扰,关键字请用学号末3位*/

int shmid_1,shmid_2;

if ((shmid_1=shmget(key,1000,0644|IPC_CREAT))==-1){

        perror("shmget shmid_1");exit(1);

}

printf("First shared memory identifier is %d\n",shmid_1);

if ((shmid_2=shmget(IPC_PRIVATE,20,0644))==-1){

        perror("shmget shmid_2");exit(2);

}

printf("Second shared memory identifier is %d\n",shmid_2);

exit(0);

}

运行结果:

Ipcs查看:

再次运行:

再次用ipcs查看:

Ipcrm删除

分析:

成功,返回共享内存段的标识符,内核中用于唯一的标识一个对象。对存在于内核存贮空间中的每个共享内存段,内核均为其维护着一个数据结构shmid_ds。

失败,返回-1,设置errno。

①第一个参数key(键值)用来创建IPC标识符,shmget()返回的标识符与key值一一对应,不同的key值返回不同的标识符。

②第二个参数size,决定了共享内存段的大小(若访问已存在的内存段,该参数可设为0)。有最大字节数的限制

③第三个参数shmflag,用于设置访问权限及标识创建条件。

对两次的结果进行比较:两次运行结束后的 第二个共享标识符是不一样的。在用ipcs查看时,共享内存段中的关键字,共享内存标识符,访问权限,字节等都是不一样的。

(4)每个同学登陆两个窗口,先在一个窗口中运行例3程序1(或者只登陆一个窗口,先在该窗口中以后台方式运行程序1),然后在另一个窗口中运行例3程序2,观察程序的运行结果并分析。运行结束后可以用ctrl+c结束程序1的运行。

实验代码:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define SHMKEY 208  /*在实际实验过程中,为了避免每个同学建立的共享存储区关键字一样而相互干扰,关键字请用学号末3位*/

#define K  1024

int shmid;

main ()

 {

int i,*pint;

char *addr;

extern char * shmat ();

extern cleanup ();

for(i=0;i<20;i++) signal(i,cleanup);

shmid=shmget(SHMKEY,16*K,0777|IPC_CREAT); /*建立16K共享区SHMKEY */

addr=shmat(shmid,0,0);/*挂接,并得到共享区首地址 */

printf ("addr 0x%x\n",addr);

pint=(int *)addr;

for (i=0;i<256;i++) *pint++=i;

pause();/*等待接收进程读 */

 }

cleanup()

{

shmctl(shmid,IPC_RMID,0);

exit ();

 }

运行结果:

分析:

首先系统通过调用shmctl对shmid指向的内存段进行删除操作,接着系统调用shmget创建一个16*1024字节的共享内存段,成功返回共享内存段的标识符给shmid,系统再次调用shmat连接内存段,返回该共享内存段连接到调用进程地址空间上的地址addr。

实验代码:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define SHMKEY 208  /*在实际实验过程中,为了避免每个同学建立的共享存储区关键字一样而相互干扰,关键字请用学号末3位*/

#define K  1024

int shmid;

main ()

 {

int i,*pint;

char *addr;

extern char * shmat ();

shmid=shmget(SHMKEY,8*K,0777);/*取共享区SHMKEY的id */

addr=shmat(shmid,0,0);/*连接共享区*/

pint=(int *)addr;

for (i=0;i<256;i++)

printf("%d\n",*pint++);/*打印共享区中的内容*/

}

运行结果:


分析:

例3_1程序后台运行时,该程序开始执行,系统调用shmget创建一个8*1024字节的共享内存段,再通过调用shmat挂接内存段,由系统选择挂接地址,最终输出转换后的挂接地址。

需要指出的是,共享存储区机制只为通信进程提供了访问共享存储区的操作条件,而对通信的同步控制则要依靠信号量机制等才能完成。

(5)      编写程序:使用系统调用shmget(),shmat(),shmdt(),shmctl(),编制程序。要求在父进程中生成一个30字节长的私有共享内存段。接下来,设置一个指向共享内存段的字符指针,将一串大写字母写入到该指针指向的存贮区。调用fork()生成子进程,让子进程显示共享内存段中的内容。接着,将大写字母改成小写,子进程修改共享内存中的内容。之后,子进程将脱接共享内存段并退出。父进程在睡眠5秒后,在此显示共享内存段中的内容(此时已经是小写字母)。

实验代码:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define SHMKEY 208  /*在实际实验过程中,为了避免每个同学建立的共享存储区关键字一样而相互干扰,关键字请用学号末3位*/

#define K  1024

int shmid;

main()

{

int i;

char *pint;

char *addr;

extern char * shmat ();

extern cleanup ();

for(i=0;i<20;i++) signal(i,cleanup);

shmid=shmget(SHMKEY,16*K,0777|IPC_CREAT); /*建立16K共享区SHMKEY */

addr=shmat(shmid,0,0);/*挂接,并得到共享区首地址 */

printf ("addr 0x%x\n",addr);

pint=(char *)addr;

for (i='a';i<='e';i++) *pint++=i;

pause();/*等待接收进程读 */

}

cleanup()

{

shmctl(shmid,IPC_RMID,0);

exit ();

}

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define SHMKEY 208  /*在实际实验过程中,为了避免每个同学建立的共享存储区关键字一样而相互干扰,关键字请用学号末3位*/

#define K  1024

int shmid;

main ()

 {

int i;

char *pint;

char *addr;

extern char * shmat ();

shmid=shmget(SHMKEY,8*K,0777);/*取共享区SHMKEY的id */

addr=shmat(shmid,0,0);/*连接共享区*/

pint=(char *)addr;

for (i=0;i<5;i++)

printf("%c\n",-32+*pint++);/*打印共享区中的内容*/

}

结果无法正确运行

四、         实验心得

通过本次实验了解了管道进程间通信形式,,管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道; 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统 。数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。基本达到了本次实验的要求。另外,对于共享内存也有一定的了解,学会通过创建多个管道实现父子进程间的通信,对于共享内存通信的工作机制也有了一定的了解,总之,本次实验自己收获了很多。


第二篇:操作系统实验报告十二


《采用无缓冲方式实现文件读/写》实验报告

实验序号: 十二 实验项目名称:采用无缓冲方式实现文件读/写—共享内存

操作系统实验报告十二

操作系统实验报告十二

操作系统实验报告十二

操作系统实验报告十二

操作系统实验报告十二

操作系统实验报告十二

更多相关推荐:
操作系统实验报告 完全版

《计算机操作系统》实验报告班级:姓名:学号:实验一进程控制与描述一、实验目的通过对Windows2000编程,进一步熟悉操作系统的基本概念,较好地理解Windows2000的结构。通过创建进程、观察正在运行的进…

操作系统实验报告

操作系统实验报告实验名称理解UNIXLINUXShell及UNIX的进程树成绩专业班级计科姓名学号联系电话实验日期20xx年12月5日实验报告日期20xx年12月5日一实验名称理解UNIXLINUXShell及...

操作系统实验报告

目录实验一进程的创建2实验二进程控制3实验三进程的管道通信4实验四消息通信6实验五进程调度算法8实验六FIFO页面置换算法12实验七LRU页面置换算法14实验八磁盘调度18实验一进程的创建1一实验目的编写一段程...

操作系统实验报告

操作系统实验报告学号姓名班级实验一实验报告实验名称并发程序设计实验1实验目的掌握在程序中创建新进程的方法观察并理解多道程序并发执行的现象实验原理fork建立子进程子进程得到父进程地址空间的一个复制返回值成功时该...

计算机操作系统课程设计报告

《操作系统原理》实验报告院(部):管理工程学院专业:信息管理与信息系统实验项目:实验一二三五班级:信管102姓名:学号:目录引言.........................................…

操作系统课程设计实验报告

操作系统课程设计实验报告姓名学号班级地点20xx年月日任务说明共完成四个任务任务一IO系统调用开销比较任务二实现一个简单的shell任务三进程线程同步任务四文件内容的并行搜索其中任务一完成了标准c和unix下的...

操作系统实验报告

郑州航空工业管理学院计算机科学与应用系课程设计报告操作系统原理操作系统课程设计目录1题目简述22需求分析221设计思想222要求323任务324运行环境325开发工具33概要设计与详细设计331系统流程图332...

操作系统上实验报告3

操作系统实验三报告实验题目进程管理及进程通信实验环境虚拟机Linux操作系统实验目的1利用Linux提供的系统调用设计程序加深对进程概念的理解2体会系统进程调度的方法和效果3了解进程之间的通信方式以及各种通信方...

操作系统实验报告

一实验内容模拟时钟中断的产生及设计一个对时钟中断事件进行处理的模拟程序二实验目的现代计算机系统的硬件部分都设有中断机构它是实现多道程序设计的基础中断机构能发现中断事件且当发现中断事件后迫使正在处理器上执行的进程...

操作系统实验报告

操作系统实验报告,内容附图。

操作系统实验报告

武汉理工大学学生实验报告书实验课程名称操作系统开课学院计算机科学与技术学院指导老师姓名学生姓名学生专业班级20xx20xx学年第一学期实验课程名称操作系统实验课程名称操作系统实验课程名称操作系统实验课程名称操作...

操作系统实验报告

实验一Windows线程的创建与撤销一实验目的1熟悉Windows系统提供的线程创建与撤销系统调用2掌握Windows系统环境下线程的创建与撤销方法二实验内容正确使用CreateThreadExitThread...

操作系统实验报告(38篇)