一、实验目的

1、了解和熟悉Linux支持的消息通信机制、管道道通信、共享存储区机制及信息量机制。

2、掌握利用Linux系统的进程通信机制(IPC)实现进程间交换数据的方法。

二、实验内容

1、进程通信

使用系统调用pipe()建立一条管道线:两个子进程P1和P2分别向管道各写一句话:

Child 1 is sending a message!

Child 2 is sending a message!

父进程则从管道中读出来自两个了进程的信息,显示在屏幕上。

要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。(可以通过sleep()将自身进入睡眠)

2、消息的创建,发送和接收

(1) 使用系统调用msgget (), msgsnd (), msgsrv ()及msgctl () 编制一长度为1K的消息(如个人通信录信息)的发送和接收程序.

(2) 使用共享存储区相关的系统调用  shmget (),shmat (),sgmdt (),shmctl (),编制一个与上述功能相同的程序.

(3) 比较上述两种消息通信机制中数据传输的时间。

三、设计原理(或方案)及相关算法

1. 进程通信:

创建一条管道,子进程写入数据,父进程写出数据。在父进程中使用 wait() 函数,这样在子进程执行完毕之前,父进程一直要等待。

调用pipe()建立一条管道,两个子进程分别向管道写入一句话,在父进程中使用wait()函数,使父进程等待子进程执行结束,依次输出P1、P2发来的消息。

2. 消息的创建,发送和接收

2.1:

(1)用一个程序作为“引子”,先后fork()两个进程,SERVER和CLIENT,进行通信

(2)SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER。SERVER每接受到一个消息后显示一句“(Server)received”,然后发送一个返回消息给CLIENT端,显示一句“(Server)sent”。

(3)CLIENT端使用key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后一个消息,即是SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(Client)sent”,等接受SERVER端的返回消息后,显示一句“(Client)received”,再在发送下一条消息。

(4)父进程在SERVER和CLIENT都退出后结束。

2.2:

(1)为了便于操作和观察结果,用一个 程序为“引子”,先后fork( )两个子进程,SERVER 和 CLIENT,进行通信。

(2)SERVER端建立一个KEY为75的共享区,并将第一个字节置为-1.作为数据空的标志.等待其他进程发来的消息.当该字节的值发生变化时,表示收到了该消息,进行处理.然后再次把它 的值设为-1.如果遇到的值为0,则视为结束信号,取消该队列,并退出SERVER.SERVER每接 收到一次数据后显示”(server)received”.

(3)CLIENT端建立一个为75的共享区,当共享取得第一个字节为-1时, Server端空闲,可发送 请求. CLIENT 随即填入9到0.期间等待Server端再次空闲.进行完这些操作后, CLIENT 退出. CLIENT每发送一次数据后显示”(client)sent”.

(4)父进程在SERVER和CLIENT均退出后结束.

四、结果分析

题目一:Pipe()函数实现管道通信

(1)进入源代码文件放置目录,并对原文件进行编译

(2)运行

题目二:

1.使用系统调用msgget(), msgsnd(), msgsrv()及msgctl()编制一长度为1K的消息(如个人通信录信息)的发送和接收程序.

(1)编译

(2)运行

每当Client发送一个消息后,server接收该消息,Client再发送下一条。“(Client)sent”和“(server)received”的字样在屏幕上交替出现。

2. 使用共享存储区相关的系统调用  shmget(),shmat(),sgmdt(),shmctl(),编制一个与上述功能相同的程序

在运行的过程中,发现每当client发送一次数据后,server要等大约0.1秒才有响应。同样,之后client又需要等待大约0.1秒才发送下一个数据。当client端发送了数据后,并没有任何措施通知server端数据已经发出,需要由client的查询才能感知。此时,client端并没有放弃系统的控制权,仍然占用CPU的时间片。只有当系统进行调度时,切换到了server进程,再进行应答。

3. 比较上述两种消息通信机制中数据传输的时间

当数据量比较少时,第一种方式传输数据比利用第二种方式传输数据所有的时间要少一些。

当消息队列和共享区建立好后, 共享区的数据传输受到了系统硬件的支持, 不耗费多余的资源; 而消息传递,由软件进行控制和实现, 需要消耗一定的CPU资源. 因此, 共享区更适合频繁和大量的数据传输。

五、源程序

 1. pipe.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>int main(){int fd[3], pid1, pid2;char OutPipe[100], InPipe[100];   //建立管道文件,并将文件描述词通过数组返回
pipe(fd);  //父进程建立管道while ((pid1 = fork()) == -1) ;    //创建子进程pid1,直到成功
if (pid1 == 0){lockf(fd[1], 1, 0);  //给fd[1]文件上锁 ,实现进程互斥sprintf(OutPipe, "Child process 2 is sending a message!");     //格式化字符串write(fd[1], OutPipe, 50);sleep(1);    //休眠lockf(fd[1], 0, 0);    //给fd[1]文件解锁exit(0);}else{    //执行父进程while ((pid2 = fork()) == -1) ;   //创建子进程pid2,直到成功if (pid2 == 0){lockf(fd[1], 1, 0);sprintf(OutPipe, "Child process 1 is sending a message!");  write(fd[1], OutPipe, 50);sleep(1);lockf(fd[1], 0, 0);exit(0);   //关闭pid2}else{read(fd[0], InPipe, 50);printf("%s\n", InPipe);wait(0);//从fd[0]代表的读端 读取50字节 保存在buf缓冲区之后,文件的当前读写指针向后移动50字节read(fd[0], InPipe, 50);printf("%s\n", InPipe);exit(0);   //结束父进程}}return 0;
}

 2.1 MessageOne

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#define MSGKEY 75          //定义关键词MEGKEY
struct msgform                //定义消息结构
{long mtype;char mtexe[1030];         //文本长度
}msg;
int msgqid,i;void CLIENT(){int i;msgqid=msgget(MSGKEY,0777);    //创建消息队列for(i=10;i>=1;i--){msg.mtype=i;printf("(client)sent\n");msgsnd(msgqid,&msg,1024,0);       //发送消息msg入msgid消息队列}exit(0);
}void SERVER(){ msgqid=msgget(MSGKEY,0777|IPC_CREAT); //创建一个所有用户都可以读、写、执行的队列do{msgrcv(msgqid,&msg,1030,0,0);    //从队列msgid接受消息msgprintf("(server)receive\n");}while(msg.mtype!=1);             //消息类型为1时,释放队列msgctl(msgqid, IPC_RMID,0);      //消除消息队列的标识符exit(0);
}int main(){if(fork())       //父进程SERVER();else           //子进程CLIENT();wait(0);wait(0);
}

 2.2 MessageTwo

#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<wait.h>
#include<sys/types.h>
#include<sys/msg.h>
#include<sys/ipc.h>
#include <sys/shm.h>
#define SHMKEY  75                   //定义共享区关键词
int shmid,i;
int *addr;void CLIENT(){    int i;    shmid=shmget(SHMKEY,1024,0777);    //获取共享区,长度1024,关键词SHMKEYaddr=shmat(shmid,0,0);                //共享区起始地址为addr    for(i=9;i>=0;i--) {        while(*addr!= -1);                          printf("(client)sent\n");                 //打印(client)sent      *addr=i;                             //把i赋给addr  }    exit(0);
}void SERVER(){     shmid=shmget(SHMKEY,1024,0777|IPC_CREAT);    //创建共享区   addr=shmat(shmid,0,0);                           //共享区起始地址为addr do {    *addr=-1;    while(*addr==-1);    printf("(server)received\n");               //服务进程使用共享区    }while(*addr);    shmctl(shmid,IPC_RMID,0);    exit(0);}int main(){    if(fork())SERVER();    if(fork())CLIENT();    wait(0);    wait(0);
}

OS实验三【进程通信】相关推荐

  1. 2020 操作系统 实验二 进程通信

    实验二.进程通信 一.实验名称 进程通信 二.实验目的 掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法. 三.实验原理 邮箱机制类似于日常使用的信 ...

  2. linux软中断通信的基本原理,实验三 软中断通信

    实验三 软中断通信 实验目的 1.了解什么是信号 2.熟悉LINUX系统中进程之间软中断通信的基本原理 实验内容 1.编写程序:用fork( )创建两个子进程,再用系统调用signal( )让父进程捕 ...

  3. Linux实验三父子进程每隔3秒,实验三进程的创建和简单控制(学生分析.doc

    实验三进程的创建和简单控制(学生分析 实验 进程的创建和简单控制 实验目的: 掌握进程的概念和进程的状态,对进程有感性的认识: 掌握进程创建方法: 认识进程的并发执行,了解进程族之间各种标识及其存在的 ...

  4. 操作系统——实验贰——进程通信(一)管道及共享内存

    一. 实验目的 熟悉并掌握管道机制,并实现进程间通信 熟悉并掌握共享内存机制,并实现进程间通信 二. 实验内容 任务一: (1)阅读以上父子进程利用管道进行通信的例子(例1),写出程序的运行结果并分析 ...

  5. OS实验:进程管理与死锁

    进程管理与死锁 一. 实验目的 二. 实验内容 三. 实验过程 3.1 在Linux 下创建一对父子进程 让父进程提前结束 让父进程后结束 3.2 在Linux下创建两个线程A和B,循环输出数据或字符 ...

  6. 操作系统实验·Linux进程通信与内存管理

    预备知识 Linux进程的数据结构 在Linux中,进程用task_struct表示,所有进程被组织到以init_task为表头的双向链表中(见[include/linux/sched.h]SET_L ...

  7. ZUCC_操作系统实验_Lab7进程通信---共享内存

    lab7进程通信-共享内存 一.利用共享内存实现生产者/消费者问题的解决方案 1.代码 #include<stdio.h> #include<stdlib.h> #includ ...

  8. GB28181系统设计(三)-进程通信让python获取共享内存数据

    GB28181系统设计 一 事件设计 GB28181系统设计 二 kdtree 算法 这一节说到了GB28181 系统接收到RTP包后,解码后交付给python做图像识别 流媒体服务依然是c++主打, ...

  9. linux共享存储通信实验,Linux进程通信——共享存储

    共享内存是进程间通信最有用的方式,也是最快的IPC形式.共享内存是说:同一块内存被映射到多个进程的地址空间.但是共享内存并不提供同步机制,因此需要互斥锁或者信号量.使用共享内存唯一需要注意的是:当前如 ...

最新文章

  1. 新版本找不到tf.contrib的解决方案
  2. 学习okhttp wiki--Connections.
  3. shell中字符串操作【转】
  4. Django后台管理之商品分类
  5. linux思考与实验答案,linux课后习题答案教材课后习题参考答案
  6. Python2.5.4移植到arm-linux
  7. 软件项目组织架构安排
  8. FlashBuilder 4.6破解方法
  9. CISCO路由基本配置命令
  10. 浅出深入统计学(一)
  11. 74CMS 3.0 CSRF漏洞
  12. 还在为挖不到漏洞烦恼?还在为如何才能升职加薪困惑?听听徐老师怎么说.........
  13. execute immediate使用方法
  14. DGL官方教程--图注意力网络(GAT)
  15. Win11终端管理员打不开解决方法
  16. python绘制多边形样例_Python绘制多边形
  17. SAP 后台表查询方法及消息报错定位方法
  18. 网页中验证码无法正常显示
  19. kali安装卡在最后一步_解决kali安装过程中配置网络失败问题
  20. (二-1)多码之间的进制转换【计算机组成原理】

热门文章

  1. 4种黄金结尾,让点赞率倍增
  2. 《HR黑话大全》:那些残忍的潜台词
  3. 用tensorflow求解吴恩达的机器学习练习题(ex1)
  4. 基于shell,python 简易数据采集流程图
  5. Selenium操作隐藏的元素
  6. 冰shader_干货 | UnityShader Demo01之冰块材质
  7. 进程与线程的联系和区别?
  8. Win10提示我们找不到你的相机?驱动人生告诉你如何判断摄像头是否正常
  9. 官匹显示日本服务器负载过高,csgo正在重新连接游戏服务器
  10. 区块链开发公司浅析区块链技术对银行的影响