实验四:进程间通信编程实验

一【实验目的】

1.理解进程间通信原理;
2.掌握进程中信号量、共享内存、消息队列相关的函数的使用;
3.支撑网络空间安全专业的专业核心能力、综合创新能力。

二【实验要求】

以下每个实验均要求:
1.“实验源代码”处:粘贴所编写的程序源码,务必添加关键语句的注释;
2.“实验结果”:截图(包括编写的程序和运行结果)粘贴到“实验结果”下方,截图需看到本人的名字及学号;
3.有“讨论”的题目,请务必认真回答;

三【实验内容】

4-1 编写程序实现以下功能:
利用匿名管道实现父子进程间通信,要求
父进程发送字符串“hello child”给子进程;
子进程收到父进程发送的数据后,给父进程回复“hello farther”;
父子进程通信完毕,父进程依次打印子进程的退出状态以及子进程的pid。
【源代码】

4-2 编写程序实现以下功能:利用匿名管道实现兄弟进程间通信,要求兄进程发送字符串“This is elder brother ,pid is (兄进程进程号)”给弟进程;弟进程收到兄进程发送的数据后,给兄进程回复“This is younger brother ,pid is(第进程进程号)”;
实验步骤:父进程先创建一个子进程(这个就是兄进程) 然后通过判断进入父进程中,然后再次创建一个进程 这个进程就是弟进程 父进程先创建一个子进程(这个就是兄进程) 然后通过判断进入父进程中,然后再次创建一个进程 这个进程就是弟进程。
【源代码】

4-3 编写程序实现以下功能:
利用有名管道文件实现进程间通信,要求
写进程向有名管道文件写入10次“hello world”;
读进程读取有名管道文件中的内容,并依次打印。
【源程序】

4-4 编写代码完成以下功能:
创建共享内存,写进程通过键盘不断向内存写入“hello world”;
如果结束写操作,则通过键盘输入“end”;
读进程从共享内存读取数据,并打印。直到读到“end”为止。
【源程序】

4-5 编写代码完成以下功能:
进程A向消息队列发送消息“hello,world”
进程B从消息队列读取消息,并打印。
进程C向消息队列发送“自己在姓名”
进程D从消息队列中取出姓名字符串,并打印

消息队列也叫报文队列,是一个消息的链表。可以把消息看作是一个记录,具有特定的格式以及优先级。对消息队列具有写权限的进程可以按照一定的规则向消息队列中添加消息,而对消息队列具有写权限的进程可以从消息队列中读走消息。和管道相似的是,消息一旦从消息队列中被读走,则消息队列中便不在存在此条消息。

补充知识:IPC消息队列的缺省最大数为16;每个消息缺省最大值为8192字节;队列中的最大值缺省为16384字节;每个消息队列都有其对应的属性信息,存储在struct_msqid_ds结构体中。每个消息队列都有一个对应的id,标识消息队列的唯一性。
【源程序】

4-6(选做) 在文件读写代码(commu-file-server.c和commu-file-client.c)的基础上,编写程序实现使用信号量机制来协调读、写进程对文件的访问。
【源程序】

commu-file-server.c
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>main(int argc, char * argv[])
{int fd;time_t now;char * message;if(argc!=2){printf("errror usage!\nusage: server filename\n");exit(1);}if((fd=open(argv[1],O_CREAT|O_WRONLY|O_TRUNC,0644))==-1){perror("open");exit(1);}while(1){//time:获得时间参数,ctime:将时间转换为字符串time(&now);//获取当前日历时间(从1970-01-01 00:00:00到现在的秒数),返回值存储在变量nowmessage=ctime(&now);//返回带格式的日期和时间信息if((lseek(fd,0,SEEK_SET))==-1){perror("lseek");exit(1);}if(write(fd,message,strlen(message))==-1){perror("write");exit(1);}sleep(1);}
}commu-file-client.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>main(int argc, char *argv[])
{int fd,len;char buf[128];if(argc!=2){printf("error usage!\nusage: client filename");exit(1);}if((fd=open(argv[1],O_RDONLY))==-1){perror("open");exit(1);}while((len=read(fd,buf,128))>0){write(1,buf,len);}close(fd);
}

附录:

Linux下进程通信相关函数有:

信号量

信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。要调用的第一个函数是semget,用以获得一个信号量ID。
int semget(key_t key, int nsems, int flag);
key是IPC结构的关键字,flag将来决定是创建新的信号量集合,还是引用一个现有的信号量集合。nsems是该集合中的信号量数。如果是创建新 集合(一般在服务器中),则必须指定nsems;如果是引用一个现有的信号量集合(一般在客户机中)则将nsems指定为0。
semctl函数用来对信号量进行操作。
int semctl(int semid, int semnum, int cmd, union semun arg);
不同的操作是通过cmd参数来实现的,在头文件sem.h中定义了7种不同的操作,实际编程时可以参照使用。
semop函数自动执行信号量集合上的操作数组。
int semop(int semid, struct sembuf semoparray[], size_t nops);
semoparray是一个指针,它指向一个信号量操作数组。nops规定该数组中操作的数量。
ftok原型如下:
key_t ftok( char * fname, int id )
fname就是指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽然为int,但是只有8个比特被使用(0-255)。
当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回。

共享内存

共享内存是运行在同一台机器上的进程间通信最快的方式,因为数据不需要在不同的进程间复制。通常由一个进程创建一块共享内存区,其余进程对这块内存区进行读写。首先要用的函数是shmget,它获得一个共享存储标识符。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, int size, int flag);
当共享内存创建后,其余进程可以调用shmat()将其连接到自身的地址空间中。
void *shmat(int shmid, void *addr, int flag);
shmid为shmget函数返回的共享存储标识符,addr和flag参数决定了以什么方式来确定连接的地址,函数的返回值即是该进程数据段所连接的实际地址,进程可以对此进程进行读写操作。
断开共享内存连接:
与shmat函数相反,shmdt是用来断开与共享内存附加点的地址,禁止本进程访问此片共享内存
函数原型
int shmdt(const void *shmaddr)
函数传入值
shmaddr:连接的共享内存的起始地址
函数返回值
成功:0
出错:-1,错误原因存于error中
附加说明
本函数调用并不删除所指定的共享内存区,而只是将先前用shmat函数连接(attach)好的共享内存脱离(detach)目前的进程
错误代码
EINVAL:无效的参数shmaddr。

消息队列

消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。
1.创建新消息队列或取得已存在消息队列
原型:int msgget(key_t key, int msgflg);
参数:
key:键值,可以指定,也可以由函数ftok生成。
msgflg:IPC_CREAT值,若没有该队列,则创建一个并返回新标识符;若已存在,则返回原标识符。
 IPC_EXCL值,若没有该队列,则返回-1;若已存在,则返回0。
2.向队列读/写消息
原型:
msgrcv从队列中取用消息:
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
msgsnd将数据放到消息队列中:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数:
msqid:消息队列的标识码
msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息
msgsz:消息的大小。
msgtyp:从消息队列内读取的消息形态。如果值为零,则表示消息队列中的所有消息都会被读取。
  msgflg:用来指明核心程序在队列没有数据的情况下所应采取的行动。
3.设置消息队列属性
原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
参数:msgctl 系统调用对 msgqid 标识的消息队列执行 cmd 操作,系统定义了 3 种 cmd 操作: IPC_STAT , IPC_SET , IPC_RMID
IPC_STAT : 该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。
IPC_SET : 该命令用来设置消息队列的属性,要设置的属性存储在buf中。
IPC_RMID : 从内核中删除 msqid 标识的消息队列。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/507431.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

细粒度图像分类_1.1、 图片分类

记录图像分类论文资源列表。图片分类任务可以分为&#xff1a;粗粒度图片分类、细粒度图片分类。2012 AlexNet &#xff1a;ImageNet Classification with Deep Convolutional Neural Networks。2014 GoogLeNet&#xff1a;Going Deeper with Convolutions。Rethinking the Inc…

diy服务器个人主机_Re:从零开始的服务器-微型服务器DIY手记

国际象棋测试4-Chess Benchmark.png (25.64 KB, 下载次数: 63)2017-3-22 19:43 上传RAR benchmarkWinRAR自带的基准测试7-RARbench.png (15.8 KB, 下载次数: 54)2017-3-22 19:45 上传7-zip benchmark7zip自带的基准测试8-7zipbench.png (31.2 KB, 下载次数: 70)2017-3-22 19:45…

实验五:线程编程实验

一【实验目的】 1.理解线程环境、线程的生命周期&#xff0c; 2.理解线程同步&#xff0c;掌握内核函数的基本用法。 3.支撑网络空间安全专业的专业核心能力、综合创新能力。 二【实验要求】 以下每个实验均要求&#xff1a; 1.“实验源代码”处&#xff1a;粘贴所编写的程序…

where里能用max吗_超市里四五元钱的速冻饺子能买吗?

展开全部我家里都特别喜欢吃带馅的食物&#xff0c;尤其是我儿子只要是饺子和馄饨&#xff0c;吃起来准没够。62616964757a686964616fe59b9ee7ad9431333433653938包饺子虽然不是什么力气活&#xff0c;但是有时候做起来也感觉太过繁琐&#xff0c;尤其是孩子要吃的时候&#xf…

python的迭代_迭代法 python

详解迭代器的使用 | 手把手教你入门Python之八十上一篇&#xff1a;自定义异常 | 手把手教你入门Python之七十九下一篇&#xff1a;生成器 | 手把手教你入门Python之八十一本文来自于千锋教育在阿里云开发者社区学习中心上线课程《Python入门2020最新大课》&#xff0c;主讲人姜…

实验六:套接字编程实验

一【实验目的】 1.掌握面向连接的套接字编程框架&#xff1b; 2.掌握面向无连接的套接字编程框架; 3.掌握I/O复用、套接字选项设置&#xff1b; 4.掌握非阻塞式I/O。 二【实验要求】 以下每个实验均要求&#xff1a; 1.“实验源代码”处&#xff1a;粘贴所编写的程序源码&am…

idea代码回滚_IDEA远程仓库版本回滚

使用 git 进行项目的版本控制时&#xff0c;肯定会遇到回滚版本的情况&#xff0c;回滚有两种&#xff0c;一种是本地仓库回滚&#xff0c;另外一种是远程仓库回滚。以下详细讲解两种回滚方式&#xff0c;本文主要讲解远程回滚&#xff0c;以及常见使用误区。本地仓库回滚本地回…

AppScan api登录接口 postman_【Postman】12 Postman monitor功能使用

通过前面的文章&#xff0c;我们已经能完成接口的Collection&#xff0c;添加断言&#xff0c;Data文件数据驱动&#xff0c;设置变量&#xff08;Data、Globals和Environment&#xff09;等等方法&#xff0c;对我们的接口进行个各种的测试&#xff0c;保证其正确性。但是还可…

Linux编程基础 5.1:管道

1 简介 Linux进程通信机制&#xff1a; 管道信号量消息队列共享内存socket通信 2 管道 管道其实质是由内核管理的一个缓冲区 形象地认为管道的两端连接着两个进程&#xff1a; 一个进程进行信息输出&#xff0c;将数据写入管道&#xff1b;另一个进程进行信息输入&#xff…

python pd Series 添加行_Python数据分析与挖掘的常用工具

Python语言&#xff1a;简要概括一下Python语言在数据分析、挖掘场景中常用特性&#xff1a;列表(可以被修改)&#xff0c;元组(不可以被修改)字典(结构)集合(同数学概念上的集合)函数式编程(主要由lambda()、map()、reduce()、filter()构成)Python数据分析常用库&#xff1a;P…

华为荣耀20和x10比较_荣耀X10和华为畅享20plus,到底哪个更值得入手?

今天&#xff0c;我接到了联通客服的电话&#xff0c;说我是老用户&#xff0c;直接给我升级成了5G套餐&#xff0c;资费没有太多的变化&#xff0c;比起以前每月月租只多了一块钱&#xff0c;也就是从原来的48元一个月变成了49元一个月&#xff0c;就加了一元钱就变成了5G套餐…

Linux编程基础 5.2:消息队列

3 消息队列 消息队列的本质是一个存放消息的链表&#xff0c;该链表由内核来维护。一个消息队列由一个标识符&#xff08;即队列key&#xff09;来标识。消息队列的通信机制传递的数据具有某种结构&#xff0c;而不是简单的字节流&#xff1b;向消息队列中写数据&#xff0c;实…

python tab和空格混用_Python编程常见十大错误,看完你自己都笑了!

关注并置顶【柠檬班】的小哥哥小姐姐胸有成“猪”使用python会出现各种各样的错误&#xff0c;以下是Python常见的错误以及解决方法。01 ValueErrorValueError: ‘Conv2d_1a_33’ is not a valid scope name其实这就是命名错误的问题&#xff0c;如果仔细看“”是我在中文下打的…

Linux编程基础 5.3:信号量

4 信号量 信号量是专门用来解决进程同步与互斥问题的一种通信机制&#xff0c;它与信号无关&#xff1b;不同于管道、FIFO以及消息队列&#xff0c;一般不用来传输数据&#xff1b;信号量包括&#xff1a;表示资源数量的非负整型变量、修改信号量的原子操作P和V、该信号量下等…

谷歌浏览器外贸版_针对谷歌SEO,你有哪些值得推荐的工具、插件、网站、app,或者技巧分享?...

接触并了解谷歌SEO也有3年了&#xff0c;这3年来&#xff0c;一直钻研这块技术和工具&#xff0c;今天刚好看到这个问题&#xff0c;就分享下。目前谷歌SEO主要分3大块&#xff0c;站内SEO(On page seo&#xff0c;做好站内优化)&#xff0c;站外SEO(off page seo 主要是外链)&…

hadoopsdk使用_hadoop部署使用问题及解决

在cygwin环境中填写路径信息时务必注意将“\”替换为“/”。hadoop文件夹名称不能包含“-”&#xff0c;比如“hadoop-2.4.0”会出错。在cygwin环境中尽管“C:\abc”和“/cygdrive/c/abc”都可以被正确识别&#xff0c;但某些软件会将前者识别为相对路径&#xff0c;从而出现错…

Linux编程基础 5.4:共享内存

5 共享内存 共享内存允许两个或多个进程访问给定的同一块存储区域。它是效率最高的一种进程通信方式&#xff0c;节省了不同进程间多次读写的时间&#xff1b;在写进程的操作尚未完成时&#xff0c;不应有进程从共享内存中读取数据。共享内存自身不限制对共享内存的读写次序&a…

升级浏览器_微软IE11浏览器 最后的升级机会

微软IE10浏览器将很快退出支持&#xff0c;许多Windows用户将没有任何安全或非安全更新&#xff0c;免费或付费辅助支持选项或在线技术内容等。幸运的是&#xff0c;微软正在为Windows用户提供升级到IE11的最后机会&#xff0c;目前IE11仅次于Firefox浏览器&#xff0c;这是互联…

jq如何获取选中option的值_【分享】如何获取变量token的值

一.什么是token客户端使用用户名跟密码请求登录服务端收到请求&#xff0c;去验证用户名与密码验证成功后&#xff0c;服务端会签发一个 Token&#xff0c;再把这个 Token 发送给客户端客户端收到 Token 以后可以把它存储起来&#xff0c;比如放在 Cookie 里或者 LocalStorage …

Linux编程基础 6.1:线程操作

1 线程操作 创建线程 挂起线程 终止线程 其它操作 1.1 创建线程 #include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); 功能&#xff1a;创建线程&#xff1b;线程调用pthread_crea…