进程间通信实验
实验3 进程间通信

实验3 进程间通信1、实验目的Linux系统的进程通信机构 (IPC) 允许在任意进程间大批量地交换数据。
本实验的目的是了解和熟悉Linux支持的消息通讯机制及信息量机制,理解进程处理信号的方法,使用用户自定义的信号处理程序。
分析进程竞争资源现象,学习解决进程互斥的方法。
了解linux系统中进程通信的基本原理。
2、实验预备内容阅读Linux系统的msg.c、sem.c和shm.c等源码文件,熟悉Linux的三种机制。
3、实验内容(1)编写一段程序,使其现实进程的软中断通信。
要求:使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按DEL键);当捕捉到中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:Child Processll is Killed by Parent!Child Processl2 is Killed by Parent!父进程等待两个子进程终止后,输出如下的信息后终止Parent Process is Killed!(2)进程的管道通信编制一段程序,实现进程的管理通信。
使用系统调用pipe()建立一条管道线;两个子进程P1和P2分别向管道中写一句话:Child 1 is sending a message!Child 2 is sending a message!而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。
要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。
(3)消息通信使用系统调用msgget( ), msgsnd( ), msgrcv( )及msgctl()编制一长度为1K的消息发送和接收的程序。
〈程序设计〉a)为了便于操作和观察结果,用一个程序为“引子”,先后fork( )两个子进程,SERVER 和CLIENT,进行通信。
b)SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。
实验5 进程间通信:消息机制

实验九进程间通信IPC:消息机制一、实验目的1.了解消息机制的相关函数。
2.了解消息队列的建立与使用。
3.能编写简单消息机制通信程序。
二、实验内容1. 建立消息队列2. 编写发送程序发送消息3. 编写接收程序接收消息三、预备知识1.创建和访问一个消息队列格式:int msgget(key_t key,int msgflag);返回值为对应消息的描述符(整型常量)。
2.发送消息(把一条消息添加到消息队列中去)格式:int msgsnd(int msqid,const void *smg_ptr,size_t msg_sz,int msgflag);3.接收消息格式:int msgrcv(int msqid,void *msg_ptr,size_t msg_sz,long int msgtype,int msgflag);4.控制和删除消息格式:int msgctl(int msqid,command,function);注意:msgsnd()和msgrcv()和msgctl()命令若执行成功,则返回0,若不成功,则返回-1。
四、实验步骤1.新建一个发送消息的程序x1.c$vi x1.c程序目的:可提示用户进行键盘输入字符,直到用户输入”end”,才结束输入。
将用户输入的内容存入消息队列,发送出去。
内容:#include<stdlib.h>#include<stdio.h>#include<string.h>#include<errno.h>#include<unistd.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#define MAX_TEXT 512struct mform{long int mtype;char mtext[MAX_TEXT];}; /*定义了消息的结构*/int main(){int running=1;struct mform msg;int msgid;char buffer[BUFSIZ];msgid=msgget((key_t)1234,0666|IPC_CREAT);/*建立消息队列*/if(msgid==-1){/*若创建不成功,则显示出错信息,结束*/ printf(“msgget failed!\n”);exit(EXIT_FAILURE);}while(running)/*当创建消息队列成功后,则循环接收用户从键盘输入的字符,直到消息内容中出现“end”为止。
实验九 System V进程间通信

实验九 System V进程间通信实验学时:4 实验类型:设计一、目的与任务目的:了解掌握操作系统消息队列、信号量的特点与功能,学会借助消息队列、信号量的功能函数进行编程。
任务:利用C语言指令编写程序调用消息队列、信号量函数,完成相应功能。
二、内容、要求与安排方式1、实验内容与要求:1)利用消息队列、信号量进行进程间的通信//创建消息队列#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/msg.h>#include<sys/ipc.h>#include<string.h>#include"mymsg.h"int main(int argc,char * argv[]){int rtn;int msqid;key_t key;mymsg msginfo;key = ftok("key.msg",1);if(key == -1){perror("ftok failed");exit(1);}msqid = msgget(key,IPC_CREAT | IPC_EXCL | 0644); if(msqid == -1){perror("msgget failed");exit(2);}return 0;}2)利用共享内存进行进程间的数据共享。
//创建共享内存,向共享内存中写入数据#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#define SHMSIZE 4096int main(int argc,char * argv[]){int shmid;key_t key;void * shmptr;key = ftok("key",1);if(argc != 2){printf("shmsrv needs a string. $shmsrv \"123456\"\n");exit(1);}if(key == -1){perror("ftok failed");exit(1);}shmid = shmget(key,SHMSIZE,IPC_CREAT | IPC_EXCL | 0600); if(shmid == -1){perror("shmget failed");exit(1);}printf("%d\n",shmid);shmptr = shmat(shmid,0,0);if(shmptr == (void *) -1){perror("shmat error");exit(1);}memcpy(shmptr,argv[1],strlen(argv[1]) + 1); if(shmdt(shmptr) == -1){perror("shmdt failed");exit(1);}return 0;}//从共享内存中读取数据#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<sys/types.h> #include<sys/ipc.h> #include<sys/shm.h>#define SHMSIZE 4096int main(int argc,char * argv[]){int shmid;key_t key;void * shmptr;char buf[SHMSIZE];key = ftok("key",1);shmid = shmget(key,SHMSIZE,SHM_R |SHM_W); if(shmid == -1){perror("shmget failed");exit(1);}shmptr = shmat(shmid,0,0);if(shmptr == (void *) -1){perror("shmat error");exit(2);}memcpy(buf,shmptr,strlen(shmptr) + 1);printf("%s\n",buf);if( shmdt(shmptr) == -1){perror("shmdt failed");exit(3);}return 0;}//删除共享内存#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<sys/types.h> #include<sys/ipc.h>#include<sys/shm.h>#define SHMSIZE 4096int main(int argc,char * argv[]){int shmid;key_t key;key = ftok("key",1);shmid = shmget(key,SHMSIZE,SHM_R |SHM_W); if(shmid == -1){perror("shmget failed");exit(1);}if(shmctl(shmid,IPC_RMID,NULL) == -1){perror("shmctl failed");exit(1);}return 0;}2、实验安排方式:采用1人1组,上机在Linux系统下进行编程实验。
系统平台实验6-进程间通信(DOC)

实验6 进程间通信一、实验目的通过本实验了解和掌握进程间通信的相关知识,(1)了解进程通信的基本原理。
(2)了解和熟悉管道通信、消息传送机制及共享存储机制。
二、实验内容1. 进程的管道通信下面程序实现进程的管道通信。
使用系统调用pipe()建立一条管道线。
阅读源程序,完成实验任务。
#include <unistd.h>#include <signal.h>#include <stdio.h>int pid1, pid2;main(){int fd[2];char outpipe[100],inpipe[100];pipe(fd);while((pid1=fork())==-1);if(pid1==0){lockf(fd[1],1,0);sprintf(outpipe,"child 1 process is sending a message!");write(fd[1],outpipe,50);sleep(5);lockf(fd[1],0,0);exit(0);}else{while((pid2=fork())==-1);if(pid2==0){lockf(fd[1],1,0); /*mutex*/sprintf(outpipe,"child 2 process is sending a message!");write(fd[1],outpipe,50);sleep(5);lockf(fd[1],0,0);exit(0);}else{wait(0);read(fd[0],inpipe,50);printf("%s\n",inpipe);wait(0);read(fd[0],inpipe,50);printf("%s\n",inpipe);exit(0);}}}实验任务:(1)读懂上面的程序,编译执行,分析为什么出现这样的执行结果。
试验二进程通信Linux试验报告

实验报告学号姓名成绩__________实验二进程通信【实验目的和要求】1、了解进程通信的概念及方法;2、了解信号量、管道;3、掌握信号量、管道和命名管道编程方法。
【实验内容】1、利用命名管道实现单机QQ聊天;2、撰写实验报告;【实验原理】1、信号量(semaphore)是为那些访问相同资源的进程以及同一进程不同线程之间提供的一个同步机制。
它不是用于传输数据,而只是简单地协调对共享资源的访问。
信号量包含一个计数器,表示某个资源正在被访问和访问的次数,用来控制多进程对共享数据的访问。
一旦成功拥有了一个信号量,对它所能做的操作只有两种:请求和释放。
当执行释放操作时,系统将该信号值减1(如果小于零,则设置为零);当执行请求操作时,系统将该信号值加1,如果加1后的值大于设定的最大值,那么系统将会挂起处理进程,直到信号值小于最大值为止。
Tuxedo 用信号量来确保在某一时刻只有一个进程对某一块共享内存进程访问。
信号量配置太低会导致Tuxedo系统应用程序无法启动。
2、管道分为两种:管道和命名管道。
管道是UNIX系统IPC的最古老形式,并且所有的UNIX系统都提供这种通信机制。
可以在有亲缘关系(父子进程或者是兄弟进程之间)进行通信,管道的数据只能单向流动,如果想双向流动,必须创建两个管道。
管道应用的一个重大缺陷就是没有名字,因此只能用于亲缘进程之间的通信。
后来以管道为基础提出命名管道(namedpipe,FIFO)的概念,该限制得到了克服。
FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。
这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。
值得注意的是,FIFO严格遵循先进先出(first in first out)规则,对管道及FIFO的读总是从开始处返回数据,对它们的写则是把数据添加到末尾。
进程通讯实验报告

一、实验目的1. 理解进程通信的概念和原理。
2. 掌握进程通信的常用方法,如管道、信号、共享内存、消息队列等。
3. 通过实验,加深对进程通信机制的理解和应用。
二、实验环境操作系统:Linux编程语言:C/C++编译器:gcc三、实验内容本次实验主要涉及以下进程通信方法:1. 管道(Pipe)2. 信号(Signal)3. 共享内存(Shared Memory)4. 消息队列(Message Queue)1. 管道(Pipe)实验内容:编写一个简单的父子进程通信程序,父进程向子进程发送数据,子进程接收数据并处理。
程序实现:```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>int main() {int pipe_fd[2];pid_t pid;char buffer[1024];// 创建管道if (pipe(pipe_fd) == -1) {perror("pipe");exit(EXIT_FAILURE);}// 创建子进程pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}if (pid == 0) { // 子进程close(pipe_fd[1]); // 关闭写端read(pipe_fd[0], buffer, sizeof(buffer)); // 读取数据printf("子进程接收到的数据:%s\n", buffer);close(pipe_fd[0]); // 关闭读端exit(EXIT_SUCCESS);} else { // 父进程close(pipe_fd[0]); // 关闭读端write(pipe_fd[1], "Hello, 子进程!", sizeof("Hello, 子进程!")); // 发送数据close(pipe_fd[1]); // 关闭写端wait(NULL); // 等待子进程结束}return 0;}```2. 信号(Signal)实验内容:编写一个简单的信号处理程序,捕捉并处理SIGINT信号。
实验三 进程间的通信
实验三进程间的通信1、实验目的学习如何利用管道机制、消息缓冲队列进行进程间的通信,并加深对上述通信机制的理解。
2、实验内容(1)了解系统调用pipe()、msgget()、msgsnd()、msgrcv()的功能和实现过程。
(2)编写一段程序,使其用管道来实现父子进程之间的进程通信。
子进程向父进程发送自己的进程标识符,以及字符串“is sending a message to parent!”。
父进程则通过管道读出子进程发来的消息,将消息显示在屏幕上,然后终止。
(3)编写一段程序,使用消息缓冲队列来实现client进程和server进程之间的通信。
server进程先建立一个关键字为SVKEY (如75)的消息队列,然后等待接收类型为REQ(如1)的消息;在收到请求消息后,它便显示字符串“serving for client”和接收到的client进程的进程标识数,表示正在为client进程服务;然后再向client进程发送一应答消息,该消息类型是client 进程的进程标识数,而正文则是server进程自己的标识数。
client进程则向消息队列发送类型为REQ的消息(消息的正文为自己的进程标识数)以取得server进程的服务,并等待server 进程发来的应答;然后显示字符串“receive reply form”和接收到的server进程的标识符。
1、client.c2、server.c3、思考题上述通信机制各有什么特点?它们分别适合于何种场合?答:管道通信的特点:(1)管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;(2)只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);(3)单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。
(4)数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。
实验三进程间通信
实验三进程间通信实验三进程间通信UNIX/LINUX 系统的进程间通信机构(IPC)允许在任意进程间大批量地交换数据。
本实验的目的是了解和熟悉LINUX 支持的信号量机制、管道机制、消息通信机制及共享存储区机制。
(一)信号机制实验目的1、了解什么是信号2、熟悉LINUX 系统中进程之间软中断通信的基本原理实验内容1、编写程序:用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按^c 键);捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:Child process1 is killed by parent!Child process2 is killed by parent!父进程等待两个子进程终止后,输出如下的信息后终止:Parent process is killed!2、分析利用软中断通信实现进程同步的机理系统调用格式signal(sig,function)头文件为#include参数定义signal(sig,function)int sig;void (*func) ( )三、参考程序#include#include#includevoid waiting( ),stop( );int wait_mark;main( ){int p1,p2,stdout;while((p1=fork( ))= =-1); /*创建子进程p1*/if (p1>0){while((p2=fork( ))= =-1); /*创建子进程p2*/if(p2>0){wait_mark=1;signal(SIGINT,stop); /*接收到^c 信号,转stop*/ waiting( ); kill(p1,16); /*向p1 发软中断信号16*/kill(p2,17); /*向p2 发软中断信号17*/wait(0); /*同步*/wait(0);printf("Parent process is killed!\n");exit(0);}else{wait_mark=1;signal(17,stop); /*接收到软中断信号17,转stop*/ waiting( );lockf(stdout,1,0);printf("Child process 2 is killed by parent!\n");lockf(stdout,0,0);exit(0);}}else{wait_mark=1;signal(16,stop); /*接收到软中断信号16,转stop*/ waiting( );lockf(stdout,1,0);printf("Child process 1 is killed by parent!\n");lockf(stdout,0,0);exit(0);}}void waiting( ){while(wait_mark!=0);}void stop( ){wait_mark=0;}四、运行结果屏幕上无反应,按下^C 后,显示Parent process is killed!五、分析原因上述程序中,signal( )都放在一段程序的前面部位,而不是在其他接收信号处。
实验四 进程通信
实验四进程间通信一、实验目的1.掌握利用管道机制实现进程间的通信的方法2.掌握利用消息缓冲队列机制实现进程间的通信的方法3.掌握利用共享存储区机制实现进程间的通信的方法4.了解Linux系统中进程软中断通信的基本原理二、实验学时2学时三、实验内容1.掌握实现进程间通信的系统调用的功能和方法进程通信,是指进程之间交换信息。
从这个意义上讲,进程之间的同步、互斥也是一种信息交换,也是一种通信。
但是,这里所说的“通信”是指进程之间交换较多的信息这样一种情况,特别是在由数据相关和有合作关系的进程之间,这种信息交换是十分必要和数量较大的。
进程间通信是协调解决多个进程之间的约束关系,实现进程共同进展的关键技术,是多道系统中控制进程并发执行必不可少的机制。
(1)进程的通信方式:a. 直接通信是指信息直接传递给接收方,如管道。
在发送时,指定接收方的地址或标识,也可以指定多个接收方或广播式地址, send(Receiver, message)。
在接收时,允许接收来自任意发送方的消息,并在读出消息的同时获取发送方的地址, receive(Sender,message)。
b. 间接通信:借助于收发双方进程之外的共享数据结构作为通信中转,如消息队列。
这种数据结构称为缓冲区或信箱。
通常收方和发方的数目可以是任意的。
(2)进程间通信的类型:a. 共享存储器系统:基于共享数据结构的通信方式:只能传递状态和整数值(控制信息),包括进程互斥和同步所采用的信号量机制。
速度快,但传送信息量小,编程复杂,属于低级通信;基于共享存储区的通信方式:能够传送任意数量的数据,属于高级通信。
b. 消息传递系统:在消息传递系统中,进程间的数据交换以消息为单位,用户直接利用系统提供的一组通信命令(原语)来实现通信。
c. 管道通信:管道是一条在进程间以字节流方式传送的通信通道。
它由OS 核心的缓冲区(通常几十KB)来实现,是单向的;在实质上,是一个有OS 维护的特殊共享文件,常用于命令行所指定的输入输出重定向和管道命令。
实验一 进程通信操作系统实验报告
验
内
容
2.用pipe()创建一个管道,然后用fork()创建两个生产进程和两个消费进程,它们之间能过pipe()传递信息。
实
验
结果
遇到问题及解决方法
int i,pid,status;
for(i=0;i<4;i++) pid=wait(*status); i,pid,status;
实
验
结果
遇到问题及解决方法
retval=clone((void*)producer,&(stack[4095]),clone_flag, (void*&arg);此语句void*后缺少),正确语句应为:
retval=clone((void*)producer,&(stack[4095]),clone_flag, (void*)&arg);
for(i=0;i<4;i++) pid=wait(&status);
if(id==1) stcopy(w_buf,"ccc\0");
else strcpy(w_buf,"ddd\0");
此语句中stcopy词语写错,应改为strcpy,即
if(id==1) strcpy(w_buf,"ccc\0");
学年第学期
操作系统课程
实验报告
学院:
专业:
班级:
姓名:
学号:
任课教师:
实验日期:2017年4月11日
实验题目
实验一进程通信
实验地点
实验目的
1.理解Linux系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据的过程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
进程间通信
调试以下程序给出运行结果并分析其程序原理:
(1)编写两个程实现进程的无名管道和有名管道通信。要求分别调
用pipe()、close()、write()、read()、popen()、pclose()、mknod()、mkfifo()、
open()实现多个进程间的通信。
#include
#include
#include
#include
#include
#include
#include
#include
#include
1.使用无名管道pipe(),进行父子进程之间的通信。
编写的程序如下:
2.以命名行为参数的管道文件的示例。(假设有一个可执行程序
chcase,从标准输入设备读字符,将小写字母转化成大写字母并输出。
主程序使用popen创建管道,实现蒋某文本文件中的字幕转化成大写
字母,其中的文本文件名作为参数传进来。)
3.创建有名管道。
4.软中断机制
#include
#include
#include
void waiting(),stop(),alarming();
int wait_mark;
main()
{
int p1,p2;
if(p1=fork()) /*创建子进程p1*/
{
if(p2=fork()) /*创建子进程p2*/
{
wait_mark=1;
signal(SIGINT,stop); /*接收到^c信号,转stop*/
signal(SIGALRM,alarming);/*接受SIGALRM
waiting();
kill(p1,16); /*向p1发软中断信号16*/
kill(p2,17); /*向p2发软中断信号17*/
wait(0); /*同步*/
wait(0);
printf("parent process is killed!\n");
exit(0);
}
else
{
wait_mark=1;
signal(17,stop);
signal(SIGINT,SIG_IGN); /*忽略 ^c信号*/
while (wait_mark!=0);
lockf(1,1,0);
printf("child process2 is killed by parent!\n");
lockf(1,0,0);
exit(0);
}
}
else
{
wait_mark=1;
signal(16,stop);
signal(SIGINT,SIG_IGN); /*忽略^c信号*/
while (wait_mark!=0)
lockf(1,1,0);
printf("child process1 is killed by parent!\n");
lockf(1,0,0);
exit(0);
}
}
void waiting()
{
sleep(5);
if (wait_mark!=0)
kill(getpid(),SIGALRM);
}
void alarming()
{
wait_mark=0;
}
void stop()
{
wait_mark=0;
}