Linux进程通信实验报告
- 格式:docx
- 大小:85.89 KB
- 文档页数:3
软件学院计算机课程实验报告册课程名称计算机操作系统实验学期 2011 年至 2012 年第 2 学期学生所在院(系)软件学院年级 11软件专业班级软工(1)班学生姓名朱水云学号 **********指导教师陈自刚实验最终成绩软件学院实验室制2012 年 4 月实验报告( 二 ) 实验名称:进程间通信实验时间:2012年4月18号实验性质应用性设计性综合性5,观察运行结果,并思考6,退出中断并写出实验报告调试过程:根据编译提示的错误进行修改四、实验结果:1消息的发送和接受运行结果:2.共享存储区的创建、附接和段接运行结果:五、疑难与小结:1.消息的创建,发送和接收小结:从理想的结果来说,应当是每当Client发送一个消息后,server 接收该消息,Client再发送下一条。
也就是说“(Client)sent”和“(server)received”的字样应该在屏幕上交替出现。
实际的结果大多是,先由 Client 发送两条消息,然后Server接收一条消息。
此后Client Server交替发送和接收消息.最后一次接收两条消息. Client 和Server 分别发送和接收了10条消息,与预期设想一致message的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造成上面现象,在多次send message 后才 receive message.这一点有助于理解消息转送的实现机理.2.共享存储区的创建、附接和段接运行的结果和预想的完全一样。
但在运行的过程中,发现每当client 发送一次数据后,server要等大约0.1秒才有响应。
同样,之后client又需要等待大约0.1秒才发送下一个数据。
出现上述的应答延迟的现象是程序设计的问题。
当client端发送了数据后,并没有任何措施通知server端数据已经发出,需要由client的查询才能感知。
此时,client端并没有放弃系统的控制权,仍然占用CPU的时间片。
试验三、linux的进程间通信试验目的:1、理解linux的进程间通信机制2、掌握和使用消息队列实现进程间通信3、掌握和使用共享主存实现进程间通信4、掌握何使用信号量实现进程同步背景知识介绍:linux继承了unix v的进程间通信机制,即消息队列、信号量和共享主存。
通常把消息、信号量和共享主存统称为system v ipc对象或ipc资源。
系统在进程请求ipc对象时在内核动态创建一个ipc数据结构并初始化,该结构定义了对该ipc对象访问的许可权,每个对象都具有同样类型的接口-函数,这组函数为应用程序提供3种服务:通过信号量实现与其他进程的同步通过消息队列以异步方式为通信频繁但数据量少的进程间通信提供服务通过共享主存,为大数据量的进程间通信提供服务1、共性描述1.1、公有的数据结构每一类ipc资源都有一个ipc_ids结构的全局变量用来描述同一类资源的共用数据,三种ipc对象对应的三个全局变量分别是semid_ds,msgid_ds 和shmid_ds。
ipc_ids结构定义如下:struct ipc_ids{int size; /*entries数组的大小*/int in_use; /*entries数组已使用的元素个数*/int max_id;unsigned short seq;unsigned short seq_max;struct semaphore sem; /*控制对ipc_ids结构的访问*/spinlock_t ary; /*自旋锁控制对数组entries的访问*/struct ipc_id* entries;};struct ipc_id{ struct ipc_perm *p;};每个ipc对象都有一个ipc_perm数据结构,用于描述其属性。
struct ipc_perm{__key_t __key; /* ipc键*/__uid_t uid; /* Owner's user ID. */__gid_t gid; /* Owner's group ID. */__uid_t cuid; /* Creator's user ID. */__gid_t cgid; /* Creator's group ID. */unsigned short int mode;/* Read/write permission. */unsigned short int __seq;/* Sequence number. */};每一个ipc对象都有一个32位的ipc键和一个ipc标识符,ipc标识符由内核分配给ipc对象,在系统内部惟一,IPC机制提供了相应的编程接口根据IPC键值获取标识符。
实验二 Linux进程通信一、实验目的1)了解有关Linux系统调用;2)学习有关Linux的进程创建,理解进程创建后两个并发进程的执行。
二、实验内容在Linux环境下,用C/C++语言编程,使用系统调用fork创建进程多个子进程。
(1) 调试并完成下列程序,完成实验要求:#include "stdio.h"#include "sys/types.h"#include "unistd.h"int main(){pid_t pid1;pid_t pid2;pid1 = fork();pid2 = fork();printf("pid1:%d, pid2:%d\n", pid1, pid2);}要求:A.请说出执行这个程序后,将一共运行几个进程。
B.观察运行结果,并给出分析与解释。
答:A.执行这个程序后,将一共运行4个进程。
A.运行结果如下:分析与解释:fork()函数能够建立子进程,且使得子进程得到父进程地址空的一个复制;而且,当创建成功时,如果是父进程则返回0,子进程则返回子进程的I D,但是,fork()创建的进程并不是从该程序开头开始执行,它只是和父进程一样继续执行后续代码,因此在之后的语句中,父子进程同时创建一个进程,就形成了四个进程,如图上所示。
所以,,在上面的截图中,第一次fork()函数时成功产生了父子进程pid分别为2775和0,第二次使用fork()函数时父子进程又各产生了一对父子进程父进程产生的父子进程的pid分别为2776和0,子进程产生的父子进程的pid分别为0和2777。
因为进程是并发的,他的调度我们无法干预,所以出现的结果并非都是一成不变的,执行多次后,输出的顺序有可能不一样。
(2)参考下面的相关程序实例,编写一个管道实验程序,实现两个进程之间的数据通信。
要求:父进程顺序写入若干个字符串,子进程顺序读出内容,并写入文件piple.txt,并显示出来。
实验三2_Linux进程间通信实验三 Linux进程间通信一、实验目的熟悉Linux下进程间通信机制,能够使用系统提供的各种通信机制实现并发进程间的数据交换。
二、实验题目分别使用Linux下的共享存储区、消息、管道等通信机制,编程实现并发进程之间的相互通信。
三、背景材料(一)需要用到的系统调用实验可能需要用到的主要系统调用和库函数在下面列出,详细的使用方法说明通过“man 2 系统调用名”或者“man 3 函数名”命令获取。
fork() 创建一个子进程,通过返回值区分是在父进程还是子进程中执行;wait() 等待子进程执行完成;getpid() 获取当前进程id;shmget() 建立一个共享存储区;shmctl() 操纵一个共享存储区;shmat() 把一个共享存储区附接到进程内存空间;shmdt() 把一个已经附接的共享存储区从进程内存空间断开;msgget() 建立一个消息队列;msgctl() 操纵一个消息队列;msgsnd() 发送消息;msgrcv() 接收消息;signal() 设置对信号的处理方式或处理过程;pipe() 打开管道;lockf() 锁定一个文件。
(二)使用共享存储区的示例程序下面程序主要用来演示共享存储区的使用方法:首先要使用shmget得到共享存储区句柄(可以新建或连接已有的共享存储区,以关键字标识),然后使用shmat挂接到进程的存储空间(这样才能够访问),当使用完后,使用shmctl释放(shmctl 还可以完成一些其他功能)。
这种使用逻辑也适用于消息和信号量。
示例程序代码如下:#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <sys/ipc.h>#include <sys/shm.h>int main(void){int x, shmid;int *shmptr;if((shmid=shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT|0666)) < 0) printf("shmget error"), exit(1);//函数原型int shmget(key_t key,int size,int shmflg); 函数用于创建(或者获取)一key键值指定的共享内存对象,返回该对象的系统标识符:shmid;size 是创个由IPC_CREAT|0666,说明新建一个权限为0666的消息队列,建的共享内存的大小,id,若其中组用户、当前用户以及其他用户拥有读写的权限若成功则返回共享内存-1 出错则为if((shmptr=(int *)shmat(shmid, 0, 0)) == (int *)-1)printf("shmat error"), exit(1);// void *shmat(int shm_id,void *shm_addr,int shmflg); shm_id标识码,shm_addr连,shmflg标志位接到的地址printf("Input a initial value for *shmptr: ");scanf("%d", shmptr);while((x=fork())==-1);if(x==0) /* child run */{printf("When child runs, *shmptr=%d\n", *shmptr);printf("Input a value in child: ");scanf("%d", shmptr);printf("*shmptr=%d\n", *shmptr);}else /* parent run */{wait();printf("After child runs, in parent, *shmptr=%d\n", *shmptr);if ( shmctl(shmid, IPC_RMID, 0) < 0 )// shmctl()函数声明:int shmctl(int shmqid, int cmd, struct shmid_ds *buf);返回值:0 on success函数用于对已创建的共享内存对象进行查询、设值、删除等操作;这个函数-1 on error:和 msgget()函数十分相似,用法也相同。
进程的管道通信实验报告一、实验目的本实验旨在通过实际操作,深入理解进程间通信(IPC)的原理,掌握管道通信的实现方法,提高对操作系统进程管理的理解。
二、实验环境实验环境为Linux操作系统,使用Shell脚本进行进程的管道通信实验。
三、实验内容1. 创建两个Shell脚本文件,分别命名为sender.sh和receiver.sh。
2. 在sender.sh中,编写一个简单的程序,用于向管道中写入数据。
程序包括一个无限循环,每次循环中随机生成一个数字并写入管道。
3. 在receiver.sh中,编写一个简单的程序,用于从管道中读取数据。
程序同样包括一个无限循环,每次循环中从管道中读取一个数字并输出。
4. 使用Shell命令将sender.sh和receiver.sh链接起来,实现进程间的管道通信。
四、实验过程1. 打开两个终端窗口,分别用于运行sender.sh和receiver.sh。
2. 在第一个终端窗口中,输入命令“bash sender.sh”运行sender.sh脚本。
该脚本将创建一个无限循环,每次循环中随机生成一个数字并写入管道。
3. 在第二个终端窗口中,输入命令“bash receiver.sh”运行receiver.sh脚本。
该脚本将创建一个无限循环,每次循环中从管道中读取一个数字并输出。
4. 观察两个终端窗口的输出,可以看到sender.sh进程向管道中写入的数字被receiver.sh进程读取并输出。
五、实验总结通过本次实验,我们成功实现了进程间的管道通信。
在实验过程中,我们深入了解了进程间通信的原理和实现方法,掌握了管道通信的基本操作。
通过实际操作,我们更好地理解了操作系统中进程管理、进程间通信的相关知识。
同时,我们也发现了一些不足之处,例如在程序中没有添加异常处理机制等。
在今后的学习中,我们将继续深入探索进程间通信的相关知识,提高自己的编程技能和系统设计能力。
第四章 Linux 进程通信(4学时)实验一信号和管道通信实验目的1.了解和掌握Linux信号处理程序设计2.了解和掌握管道的操作实验内容1.设计一个程序,由父进程创建一个子进程,在父进程中显示3行“How are you!”,然后向子进程发送软中断信号,等待子进程终止后输出结束信息“OK”,然后终止执行。
子进程中循环显示“I am child”,接受到父进程发来的软中断信号后停止循环,显示“child exited!”并终止运行。
2.设计一个程序,要求创建一个管道PIPE,复制进程,子进程向管道中写入“This is amessage!”,父进程接收到子进程终止信号后从管道中读取消息并显示。
实验步骤1.(1)编辑源程序signal.c#include<signal.h>#include<stdio.h>#include<unistd.h>int k1; /*定义全局变量k1*/void int_fun1(int sig) /*定义软中断所对应的函数*/{ k1=0;}main(){ int k,p1;while((p1=fork())==-1); /*创建子进程*/if(p1>0) /*父进程返回*/{ for(k=1;k<4;k++) /*显示3行信息*/{ printf("How are you !\n");sleep(1);}kill(p1,12); /*发子进程终止信号*/wait(0); /*等待子进程终止*/printf("OK!\n"); /*输出结束信息*/exit(0);}else /*子进程返回*/{ signal(12,int_fun1); /*预置软中断信号*/k1=1;while(k1==1) /*循环显示并等待父进程发软中断信号*/{ printf("I'm child\n");sleep(1);}printf("Child exited!\n"); /*显示子进程结束信息*/exit(0); /*向父进程发子进程终止信号*/}}(2)运行./sianal(3)结果分析子进程创建后等待父进程,父进程显示3行“How are you!”后,父进程退出循环并向子进程发送软中断信号;子进程接收到信号执行软中断处理函数修改了循环变量终止循环,显示终止消息“child exited!”并终止运行。
实验6 Linux进程通信-消息传递一、实验目的:1)掌握操作系统的进程通信原理。
2)熟悉linux的进程通信方式。
3)设计程序,实现消息传递通信。
二、实验原理:1、函数ftok头文件:#include <sys/types.h>#include <sys/ipc.h>原型:key_t ftok(char *fname,int id)说明:系统建立IPC(进程间通信)时必须指定一个ID值,通常情况下该ID值通过ftok 函数得到。
ftok函数把一个已存在的路径名和一个整数标识符转换成一个key_t值,fname 是一个存在的可访问的路径或文件,id必须不能为0。
2、函数msgget头文件:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>原型:int msgget(key_t key,int msgflg);说明:获取与某个键关联的消息队列标识,用来创建新的消息队列或获取已有的消息队列。
第一个参数是关键字值(通常是由ftok()返回的)。
然后此关键字值将会和其他已经存在于系统内核中的关键字值比较。
第二个参数为IPC_CREAT时,如果内核中没有此队列,则创建它,并且返回一个新创建的消息队列的标识符。
失败返回-1。
3、函数fgets头文件:#inclue <stdio.h>原型:char *fgets(char *s,int size,FILE *stream);说明:用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符,读到文件尾或是已读了size-1个字符为止,最后加上\0作为字符串结束。
第三个参数可以是文件流,也可以是输入流stdin。
4、比较字符串函数strncmp头文件:#include <string.h>原型:int strncmp(const char *s1,const char *s2,int n);说明:若参数s1和s2字符串相同则返回0,s1若大于s2则返回大于0的值,s1若小于s2则返回小于0的值。
实验五 Linux 进程间通信1. 实验目的1)熟悉在C 语言源程序中使用Linux 所提供的系统调用界面的方法;2)掌握Linux 中子进程的创建方法以及调度执行情况,理解进程与程序的区别; 3)掌握软中断信号的使用,了解使用软中断通信实现异步事件的方法;4)掌握父子进程使用管道进行通信的方法,了解管道通信的特点和上的限制。
2. 实验内容1) 父进程创建子进程(1) 实现父进程创建一个子进程,返回后父子进程都分别循环输出字符串“I am parent.”或“I am child.”5次,每输出1次后使用sleep(1)延时1秒,然后再进入下一循环。
(2) 在源程序中连续使用4个fork(),而不用if()进行返回值的判断,在4个fork()语言后面输出字符“A ”,观察并分析该程序编译连接执行后的输出结果。
(3) 由父进程创建一个子进程,子进程的功能史输出26个英文字母,使用execl()加载子进程的程序。
(1)(2)结果:(3)2)软中断的使用(1)编写一个程序循环显示“How are you?”,当键盘输入Ctrl+C的组合键后中断循环显示,执行软中断程序,软中断程序的功能是修改循环变量的值终止循环,然后输出“Byebye”。
输出显示结果:3)管道的使用:(1)编写一个程序,实现:父进程使用系统调用pipe()创建一个无名管道;(2)创建2个子进程,分别向管道各发下面中1条信息后结束:Child 1 is sending a message to parent!Child 2 is sending a message to parent!(1)结果:(2)输出结果:3.实验思考1)如果连续创建多个子进程而不使用条件进行各自空间的分隔,会出现什么情况?2)对实验内容2)进行改进,先输出10次“How are you?”,在此过程中使用Ctrl+C不能中断循环显示,10次以后使用Ctrl+C可以中断循环,应该做那些修改?3)管道通信与软中断通信在信息量的大小上有何区别?4)共享同一个管道进行通信的读写进程之间必须满足什么关系,为什么?。
Linux系统编程实验六进程间通信实验六:进程间通信●实验目的:学会进程间通信方式:无名管道,有名管道,信号,消息队列,●实验要求:(一)在父进程中创建一无名管道,并创建子进程来读该管道,父进程来写该管道(二)在进程中为SIGBUS注册处理函数,并向该进程发送SIGBUS信号(三)创建一消息队列,实现向队列中存放数据和读取数据●实验器材:软件:安装了Linux的vmware虚拟机硬件:PC机一台●实验步骤:(一)无名管道的使用1、编写实验代码pipe_rw.c#include#include#include#include#include#includeint main(){int pipe_fd[2];//管道返回读写文件描述符pid_t pid;char buf_r[100];char* p_wbuf;int r_num;memset(buf_r,0,sizeof(buf_r));//将buf_r初始化char str1[]=”parent write1 “holle””;char str2[]=”parent write2 “pipe”\n”;r_num=30;/*创建管道*/if(pipe(pipe_fd)<0){printf("pipe create error\n");return -1;}/*创建子进程*/if((pid=fork())==0) //子进程执行代码{//1、子进程先关闭了管道的写端close(pipe_fd[1]);//2、让父进程先运行,这样父进程先写子进程才有内容读sleep(2);//3、读取管道的读端,并输出数据if(read(pipe_fd[0],buf_r, r_num)<0){printf(“read error!”);exit(-1);}printf(“%s\n”,buf_r);//4、关闭管道的读端,并退出close(pipe_fd[1]);}else if(pid>0) //父进程执行代码{//1、父进程先关闭了管道的读端close(pipe_fd[0]);//2、向管道写入字符串数据p_wbuf=&str1write(pipe_fd[1],p_wbuf,sizof(p_wbuf));p_wbuf=&str2write(pipe_fd[1],p_wbuf,sizof(p_wbuf));//3、关闭写端,并等待子进程结束后退出close(pipe_fd[1]);}return 0;}/***********************#include#include#include#include#include#includeint main(){int pipe_fd[2];//管道返回读写文件描述符pid_t pid;char buf_r[100];char* p_wbuf;int r_num;memset(buf_r,0,sizeof(buf_r));//将buf_r初始化char str1[]="holle";char str2[]="pipe";r_num=10;/*创建管道*/if(pipe(pipe_fd)<0){printf("pipe create error\n");return -1;}/*创建子进程*/if((pid=fork())==0) //子进程执行代码{close(pipe_fd[1]);//1、子进程先关闭了管道的写端//2、让父进程先运行,这样父进程先写子进程才有内容读//3、读取管道的读端,并输出数据if(read(pipe_fd[0],buf_r, r_num)<0){printf("read1 error!");exit(-1);}printf("\nparent write1 %s!",buf_r);sleep(1);if(read(pipe_fd[0],buf_r, r_num)<0){printf("read2 error!");exit(-1);}printf("\nparent write2 %s!",buf_r);close(pipe_fd[1]);//4、关闭管道的读端,并退出exit(1);//printf("child error!");}else if(pid>0) //父进程执行代码{close(pipe_fd[0]);//1、父进程先关闭了管道的读端p_wbuf=str1;//2、向管道写入字符串数据write(pipe_fd[1],p_wbuf,sizeof(str1));sleep(1);p_wbuf=str2;write(pipe_fd[1],p_wbuf,sizeof(str2));close(pipe_fd[1]);//3、关闭写端,并等待子进程结束后退出exit(1);//printf("father error!");}return 0;}**************************/2、编译应用程序pipe_rw.c3、运行应用程序子进程先睡两秒让父进程先运行,父进程分两次写入“hello”和“pipe”,然后阻塞等待子进程退出,子进程醒来后读出管道里的内容并打印到屏幕上再退出,父进程捕获到子进程退出后也退出4、由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的读端和写端。
实验二Linux进程间通信1.实验目的(1)分析进程争用临界资源的现象,学习解决进程互斥的方法;(2)学习如何利用进程的“软中断”、管道机制进行进程间的通信,并加深对上述通信机制的理解;(3)了解系统调用pipe( )、msgget( )、msgsnd( )、msgrcv( )、msgctl( )、shmget( )、shmat( )、shmdt( )、shmctl( )的功能和实现过程,利用共享存储区机制进行进程间通信。
2.实验内容(1)进程的控制编写一段程序,使用系统调用fork()创建两个子进程。
各进程循环显示不同的信息(如20次):父进程显示:“parent:”加上进程ID,子进程分别显示:“Child1:”(或“Child2:”)加上自己的进程ID。
观察程序执行时屏幕上出现的现象,并分析原因,进一步理解各个进程争夺临界资源(显示器)的情况。
接着在程序中使用系统调用locking( )来给每一个进程加锁,实现进程之间的互斥,试观察并分析出现的现象。
(2)进程的软中断通讯编制一段程序,实现进程的软中断通讯:使用系统调用fork( )创建两个子进程;再使用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按Del键);在捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发信号;子进程捕捉到信号后分别输出下列信息后终止:Child process1 is killed by parent!Child process2 is killed by parent!父进程等待两个子进程都终止以后,输出如下信息后终止:Parent process in killed!(3)进程的管道通讯编制一段程序,实现进程的管道通讯:使用系统调用pipe( )建立一条管道线;两个子进程分别循环向这条管道写一句话:Child 1 is sending a message!Child 2 is sending a message!而父进程则循环从管道中读出信息,显示在屏幕上。
西南大学
操作系统原理
实验报告
学院:计算机与信息科学学院、软件学院
专业:网络工程
班级:16级网工班
姓名:孙明轩
学号:222015324012058
实验四进程通信
一、实验目的及要求:
1.理解Linux 系统中进程间的通信方式IPC:
•共享内存通信方式
•管道通信机制
2.编写相应程序
二、实验过程及结果:
这是已经编辑好的.c程序shm058.c和pipe058.c
用gedit shm058.c查看并编辑。
运行结果如图所示。
用gedit pipe058.c查看并编辑。
运行结果如图所示。
三、实验分析及反思:
第一个程序一开始不知道有strcpy()函数和puts()函数可以实现父子进程间的输入输出,在上网查找相关资料后终于实现了程序的目的。
第二个程序遇到的问题就是,有时候会先输出子进程的内容,而自己想要的是先输出父进程的内容,用过了sleep()函数让子进程先睡一会儿,终于达到了自己的目的。
成绩
建议。
实验六:进程间通信●实验目的:学会进程间通信方式:无名管道,有名管道,信号,消息队列,●实验要求:(一)在父进程中创建一无名管道,并创建子进程来读该管道,父进程来写该管道(二)在进程中为SIGBUS注册处理函数,并向该进程发送SIGBUS信号(三)创建一消息队列,实现向队列中存放数据和读取数据●实验器材:软件:安装了Linux的vmware虚拟机硬件:PC机一台●实验步骤:(一)无名管道的使用write(pipe_fd[1],p_wbuf,sizeof(str1));sleep(1);p_wbuf=str2;write(pipe_fd[1],p_wbuf,sizeof(str2));close(pipe_fd[1]);//3、关闭写端,并等待子进程结束后退出exit(1);//printf("father error!");}return 0;}**************************/2、编译应用程序pipe_rw.c3、运行应用程序子进程先睡两秒让父进程先运行,父进程分两次写入“hello”和“pipe”,然后阻塞等待子进程退出,子进程醒来后读出管道里的容并打印到屏幕上再退出,父进程捕获到子进程退出后也退出4、由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的读端和写端。
我们往往希望父子进程中的一个进程写一个进程读,那么写的进程最后关掉读端,读的进程最好关闭掉写端(二)信号处理#include <signal.h>{fprintf(stderr,"cannot handle SIGBUS\n");exit(EXIT_FAILURE);}pause();//将进程挂起直到捕捉到信号为止exit(0);return 0;}***************************/用signal系统调用为SIGBUS信号注册信号处理函数my_func,然后将进程挂起等待SIGBUS信号。
操作系统实验报告实验三、进程通信(一)——管道及共享内存一、实验目的熟悉和掌握LINUX系统的管道通信和共享内存通信。
二、实验内容(一)、管道通信1、实验原理:管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统。
数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。
利用系统调用pipe()可创建一个简单的管道。
int fd[2];pipe(fd);调用成功,fd[0]存放供读进程使用的文件描述符(管道出口),fd[1]存放供写程使用的文件描述符(管道入口)。
一个进程在由pipe()创建管道后,一般再fork()一个子进程,然后通过管道实现父子进程间的通信,子进程将从父进程那里继承所有打开的文件描述符。
则父子两个进程都能访问组成管道的两个文件描述符,这样子进程可以向父进程发送消息(或者相反)。
发送进程利用文件系统的系统调用write(fd[1],buf,size),把buf中size个字符送入fd[1],接收进程利用read(fd[0],buf,size),把从fd[0]读出的size个字符置入buf中。
这样管道按FIFO(先进先出)方式传送信息。
2、实验内容:#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);printf("x value in Parent Process:%d!\n",x);}}(1)阅读上述父子进程利用管道进行通信的例子,写出程序的运行结果并分析。
Linux进程通信实验报告
一、 实验目的和要求
1. 进一步了解对进程控制的系统调用方法。
2. 通过进程通信设计达到了解UNIX或Linux系统中进程通信的基本原理。
二、 实验内容和原理
1. 实验编程,编写程序实现进程的管道通信(设定程序名为pipe.c)。使
用系统调用pipe()建立一条管道线。而父进程从则从管道中读出来自
于两个子进程的信息,显示在屏幕上。要求父进程先接受子进程P1
发来的消息,然后再接受子进程P2发来的消息。
2. 可选实验,编制一段程序,使其实现进程的软中断通信(设定程序名为
softint.c)。使用系统调用fork()创建两个子进程,再用系统调用
signal()让父进程捕捉键盘上来的中断信号(即按Del键),当父进程
接受这两个软中断的其中一个后,父进程用系统调用kill()向两个子
进程分别发送整数值为16和17的软中断信号,子进程获得对应软中
断信号后分别输出相应信息后终止。
三、 实验环境
一台安装了Red Hat Linux 9操作系统的计算机。
四、 实验操作方法和步骤
进入Linux操作系统,利用vi编辑器将程序源代码输入并保存好,然后
打开终端对程序进行编译运行。
五、 实验中遇到的问题及解决
六、 实验结果及分析
基本实验
可选实验
七、 源代码
Pipe.c
#include"stdio.h"
#include"unistd.h"
main(){
int i,j,fd[2];
char S[100];
pipe(fd);
if(i=fork==0){
sprintf(S,"child process 1 is sending a message \n");
write(fd[1],S,50);
sleep(3);
return;
}
if(j=fork()==0){
sprintf(S,"child process 2 is sending a message \n");
write(fd[1],S,50);
sleep(3);
return;
}else{
wait(0);
read(fd[0],S,50);
printf("%s",S);
read(fd[0],S,50);
printf("%s",S);
return;
}
}
Softint.c
#include"stdio.h"
#include"unsitd.h"
main(){
int i,j,fd[2];
char S[100];
pipe(fd);
if(i=fork==0){
sprintf(S,"child process 1 is sending a message \n");
write(fd[1],S,50);
sleep(3);
return;
}
if(j=fork()==0){
sprintf(S,"child process 2 is sending a message \n");
write(fd[1],S,50);
sleep(3);
return;
}else{
wait(0);
read(fd[0],S,50);
printf("%s",S);
read(fd[0],S,50);
printf("%s",S);
return;
}
}