OS实验三【进程通信】_实验3 进程间的通信实验目的:学习如何利用管道机制,消息队列,共享储存机制-程序员宅基地

技术标签: C语言  # C语言  操作系统  # 操作系统OS  

一、实验目的

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接受消息msg
      printf("(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,关键词SHMKEY
    addr=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);
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_45037155/article/details/123977871

智能推荐

http隧道 java_使用java语言实现http隧道技术-程序员宅基地

文章浏览阅读119次。该楼层疑似违规已被系统折叠隐藏此楼查看此楼/***Getaparametervalue**@paramkeyString*@paramdefString*@returnString*/publicStringgetParameter(Stringkey,Stringdef){returnisStandalone?System.getProperty(ke..._java http隧道

Keepalived高可用+邮件告警_keepalived sendmail-程序员宅基地

文章浏览阅读913次。IP主机名备注192.168.117.14keepalived-master主节点192.168.117.15keepalived-slaver备节点192.168.117.100VIP1.主备节点均安装keepalived# yum install -y keepalived httpd2.主备节点均修改keepalived日志存放路径..._keepalived sendmail

SPFILE 错误导致数据库无法启动(ORA-01565)_ora01565 ora27046-程序员宅基地

文章浏览阅读469次。--==========================================--SPFILE错误导致数据库无法启动(ORA-01565)--========================================== SPFILE错误导致数据库无法启动 SQL> startup ORA-01078: failurein proce_ora01565 ora27046

功能测试基础知识(1)-程序员宅基地

文章浏览阅读6.1k次,点赞2次,收藏54次。功能测试基础知识总结_功能测试

postgresql 中文排序_pg中文排序-程序员宅基地

文章浏览阅读3.2k次,点赞3次,收藏2次。pg 中文首字母排序_pg中文排序

[Mysql] CONVERT函数_mysql convert-程序员宅基地

文章浏览阅读3.1w次,点赞23次,收藏109次。本文主要讲解CONVERT函数_mysql convert

随便推点

HTML5与微信开发(2)-视频播放事件及API属性_微信开发者工具视频快进-程序员宅基地

文章浏览阅读8.6k次,点赞2次,收藏2次。HTML5 的视频播放事件想必大家已经期待很久了吧,在HTML4.1、4.0之前我们如果在网页上播放视频无外乎两种方法: 第一种:安装FLASH插件或者微软发布的插件 第二种:在本地安装播放器,在线播放组件之类的 因为并不是所有的浏览器都安装了FLASH插件,就算安装也不一定所有的都能安装成功。像苹果系统就是默认禁用FLASH的,安卓虽然一开始的时候支持FLASH,但是在安卓4.0以后也开始不_微信开发者工具视频快进

JedisConnectionException Connection Reset_jedisconnectionexception: java.net.socketexception-程序员宅基地

文章浏览阅读5.4k次,点赞3次,收藏4次。在使用redis的过程常见错误总结1.JedisConnectionException Connection Reset参考这边文章:Connection reset原因分析和解决方案https://blog.csdn.net/cwclw/article/details/527971311.1问题描述Exception in thread "main" redis.clients...._jedisconnectionexception: java.net.socketexception: connection reset

Lua5.3版GC机制理解_lua5.3 gc-程序员宅基地

文章浏览阅读8.3k次,点赞8次,收藏42次。目录1.Lua垃圾回收算法原理简述2.Lua垃圾回收中的三种颜色3.Lua垃圾回收详细过程4.步骤源码详解4.1新建对象阶段4.2触发条件4.3 GC函数状态机4.4标记阶段4.5清除阶段5.总结参考资料lua垃圾回收(Garbage Collect)是lua中一个比较重要的部分。由于lua源码版本变迁,目前大多数有关这个方面的文章都还是基于lua5.1版本,有一定的滞后性。因此本文通过参考当前..._lua5.3 gc

手机能打开的表白代码_能远程打开,各种手机电脑进行监控操作,最新黑科技...-程序员宅基地

文章浏览阅读511次。最近家中的潮人,老妈闲着没事干,开始学玩电脑,引起他的各种好奇心。如看看新闻,上上微信或做做其他的事情。但意料之中的是电脑上会莫名出现各种问题?不翼而飞的图标?照片又不见了?文件被删了,卡机或者黑屏,无声音了,等等问题。常常让她束手无策,求助于我,可惜在电话中说不清,往往只能苦等我回家后才能解决,那种开心乐趣一下子消失了。想想,这样也不是办法啊, 于是,我潜心寻找了两款优秀的远程控制软件。两款软件...

成功Ubuntu18.04 ROS melodic安装Cartograhper+Ceres1.13.0,以及错误总结_ros18.04 安装ca-程序员宅基地

文章浏览阅读1.8k次。二.初始化工作空间三.设置下载地址四.下载功能包此处可能会报错,请看:rosdep update遇到ERROR: error loading sources list: The read operation timed out问题_DD᭄ꦿng的博客-程序员宅基地接下来一次安装所有功能包,注意对应ROS版本 五.编译功能包isolated:单独编译各个功能包,每个功能包之间不产生依赖。编译过程时间比较长,可能需要几分钟时间。此处可能会报错:缺少absl依赖包_ros18.04 安装ca

Harbor2.2.1配置(trivy扫描器、镜像签名)_init error: db error: failed to download vulnerabi-程序员宅基地

文章浏览阅读4.1k次,点赞3次,收藏7次。Haobor2.2.1配置(trivy扫描器、镜像签名)docker-compose下载https://github.com/docker/compose/releases安装cp docker-compose /usr/local/binchmod +x /usr/local/bin/docker-composeharbor下载https://github.com/goharbor/harbor/releases解压tar xf xxx.tgx配置harbor根下建立:mkd_init error: db error: failed to download vulnerability db: database download

推荐文章

热门文章

相关标签