实验五:进程间通信
进程间通信实验报告
软件学院计算机课程实验报告册课程名称计算机操作系统实验学期 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的时间片。
进程间通信
《操作系统》实验报告年级、专业、班级 姓名进程间通信实验题目实验时间 2014.11.21 实验地点 A主0410实验成绩 实验性质 □验证性 □设计性 □综合性 教师评价:□算法/实验过程正确; □源程序/实验内容提交 □程序结构/实验步骤合理;□实验结果正确; □语法、语义正确; □报告规范;其他:评价教师签名:一、实验目的1. 了解管道通信的特点,掌握管道通信的使用方法。
2. 了解消息队列通信机制及原理,掌握消息队列相关系统调用的使用方法及功能。
3. 了解Linux系统共享存储区的原理及使用方法。
二、实验项目内容1. 管道通信(1)父进程创建管道和两个子进程p1和p2。
(2)子进程p1打开给定文件(如果没有,则创建文件),并向文件中写数据,写完关闭文件,然后向管道写入一条消息“ok",目的是通知进程p2可以读取文件内容了。
(3)子进程p2通过管道读取消息,如果消息是“ok”,则打开文件,读取文件内容,并将其输出到屏幕上,关闭文件.2. 消息队列(1)父进程创建消息队列和两个子进程p1和p2。
(2)子进程p1打开给定文件(如果没有,则创建文件),并向文件中写数据,写完关闭文件,然后向消息队列写入一条消息“1",目的是通知进程p2可以读取文件内容了。
(3)子进程p2从消息队列读取消息,如果收到消息,则打开文件,读取文件内容,并将其输出道屏幕上,关闭文件。
3. 共享存储(1)由父进程建立一块共享存储区,并创建两个子进程p1,p2,父进程负责查询存储区状态,以及删除该存储区。
(2)子进程p1链接到该共享存储区,然后向存储区写入数据,写完断开链接。
(3)子进程p2链接到该共享存储区,从存储区读数据,然后断开链接。
注意:为了便于各进程对存储区访问的同步,这里使用信号量方法。
三、实验过程或算法1. 管道通信#include<unistd.h>#include<stdio.h>#include<string.h>#include<stdlib.h>int main() {int pipefd[2];pid_t pid;char buf[100];int n;为0memset(buf, 0, sizeof(buf));//clear bufif(pipe(pipefd) < 0) {perror("pipe");exit(0);}pid = fork();if(pid == 0) { //child process 1close(pipefd[0]);//close read fdchar *msg="Hello,I am a Pipe user.";write(pipefd[1], msg, 50);}else if(pid > 0) {pid = fork();if(pid == 0) { //child process 2close(pipefd[1]);//close write fdread(pipefd[0], buf, sizeof(buf));fprintf(stdout, "read from pipe is:%s\n", buf);}else if(pid > 0) exit(0);}}2.消息队列//发送消息,msqid是队列id,msg是要发送的消息void sendmsg(int msqid,mymesg msg){printf("msqid:%d,msg:%s\n",msqid,msg.mtext);if((msgsnd(msqid, &msg, sizeof(msg.mtext), IPC_NOWAIT)) != 0){//消息发送函数printf("pid_1:send msg error!\n");}else{printf("pid_1:send msg: %s succeed!\n", msg.mtext);}}//接收消息,msqid是队列idint rcvmsg(int msqid){mymesg msg={0};AIT);int msg_len = msgrcv(msqid, &msg, sizeof(msg.mtext), 0, IPC_NOW //接收消息函数if(msg_len < 0){printf("pid_2:receive msg error!\n");return 0;}printf("pid_2:recv msg: %s\n", msg.mtext);return 1;}3.共享存储创建共享存储区 shmid = shmget(IPC_PRIV A TE, SIZE, IPC_CREAT|0600 ) ;//{if ( shmid < 0 )perror("get shm ipc_id error") ;return -1 ;}pid = fork() ;子进程p1if ( pid == 0 ){ //printf("I'm child1 process,my pid is %d.\n",getpid());P操作sem_p(sem_id); //链接到存储区 shmaddr = (char *)shmat( shmid, NULL, 0 ) ;//if ( (int)shmaddr == -1 ){perror("shmat addr error") ;return -1 ;}向存储区写数据strcpy( shmaddr, "Hi,This is share memory!\n") ;//shmdt( shmaddr ) ;//断开链接V操作sem_v(sem_id); //父进程} else if ( pid > 0) {//printf("I'm father process,my pid is %d.\n",getpid());pid = fork();sleep(1);子进程2创建if(pid==0){//printf("I'm child2 process,my pid is %d.\n",getpid());P操作sem_p(sem_id); //读取存储区状态到buf中flag = shmctl( shmid, IPC_STAT, &buf) ;//{if ( flag == -1 )perror("shmctl shm error") ;return -1 ;}printf("shm_segsz =%d bytes\n", buf.shm_segsz ) ;printf("parent pid=%d, shm_cpid = %d \n", getppid(), buf.shm_cpid ) ;printf("chlid pid=%d, shm_lpid = %d \n",pid, buf.shm_lpid ) ;printf("shm_segsz =%d \n", buf.shm_perm.mode );shmaddr = (char *) shmat(shmid, NULL, 0 ) ;链接到存储区,读取其中数据if ( (int)shmaddr == -1 ){//perror("shmat addr error") ;return -1 ;}//打印数据到屏幕printf("%s", shmaddr) ;V操作sem_v(sem_id); //断开链接shmdt( shmaddr) ;//}else{perror("fork error.") ;shmctl(shmid, IPC_RMID, NULL) ;}删除该存储区shmctl(shmid, IPC_RMID, NULL) ;//return 0 ;}四、实验结果及分析和(或)源程序调试过程(包含程序使用方法、程序运行截图),实验过程中遇到的问题分析与心得体会。
实验5 进程间通信实验
实验五进程间通信实验一、实验目的1、了解什么是信号。
2、熟悉LINUX系统中进程之间软中断通信的基本原理。
3、了解什么是管道4、熟悉UNIX/LINUX支持的管道通信方式二、实验内容1、编写一段程序,使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:Child process 1 is killed by parent!Child process 2 is killed by parent!父进程等待两个子进程终止后,输出以下信息后终止:Parent process is killed!<参考程序>#include<stdio.h>#include<signal.h>#include<unistd.h>#include<sys/types.h>#include<sys/wait.h>int wait_mark;void waiting(),stop();void main(){int p1, p2;signal(SIGINT,stop);while((p1=fork())==-1);if(p1>0) /*在父进程中*/{while((p2=fork())==-1);If(p2>0) /*在父进程中*/{wait_mark=1;waiting(0);kill(p1,10);kill(p2,12);wait( );wait( );printf("parent process is killed!\n");exit(0);}else /*在子进程2中*/{wait_mark=1;signal(12,stop);waiting();lockf(1,1,0);printf("child process 2 is killed by parent!\n");lockf(1,0,0);exit(0);}}else /*在子进程1中*/{wait_mark=1;signal(10,stop);waiting();lockf(1,1,0);printf("child process 1 is killed by parent!\n");lockf(1,0,0);exit(0);}}void waiting(){while(wait_mark!=0);}void stop(){wait_mark=0;}实验要求:⑴运行程序并分析结果。
实验五 进程通信
(2)读管道 在管道创建后,希望从管道中读取数据的进程使 用读文件描述符fd[0]作为参数,调用read( )系统调用。 #include <unistd.h> ssize_t read(int fd,void *buf,size_t nbytes); 返回:读到的字节数,若已到文件尾为0,若出错 为-1。 (3)写管道 向管道中写入数据的进程使用写文件描述符fd[1] 作为参数,调用write( )系统调用。 #include <unistd.h> ssize_t write(int fd,const void *buf,size_t nbytes); 返回:若成功为已写的字节数,若出错为-1。
2. 管道是UNIX系统中最早为两个进程之间提 供的一种通信机制。管道是一种单向的、先入 先出的、无结构的、大小固定的通信通道。写 进程在管道的一端写入数据,读进程从管道的 另一端读出数据。如果两个或多个进程同时对 一个进程进行读写,那么这些进程必须使用锁 机制或者信号量机制对其进行同步。 管道分为无名管道和有名管道。无名管道 没有名字,所以只能提供给进程家族中的父子 进程间通信使用,而有名管道则用于没有家族 关系的任意两个进程之间的通信。
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. 写出试验报告。 2. 为程序添加注释。 3. 分析信号通信和管道通信各自的特点。
2. 编写一段程序,实现进程的管道通信。 使用系统调用pipe( )建立一条管道,创建两个子进程 P1和P2。 让P1和P2分别向管道各写一句话: Child 1 is sending a message! Child 2 is sending a message! 父进程则从管道中读出来自于两个子进程的信息, 显示在屏幕上。要求:父进程先接受子进程P1发来的 消息,然后再接受子进程P2发来的消息。 参考程序如下:
实验五:进程间通信
实验五:进程间通信实验五:进程间通信●实验目的:学会进程间通信方式:无名管道,有名管道,信号,共享内存●实验要求:(一)在父进程中创建一无名管道,并创建子进程来读该管道,父进程来写该管道(二)在进程中为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));/*创建管道*/if(pipe(pipe_fd)<0){printf("pipe create error\n");return -1;}/*创建子进程*/if((pid=fork())==0) //子进程执行代码{//1、子进程先关闭了管道的写端//2、让父进程先运行,这样父进程先写子进程才有内容读//3、读取管道的读端,并输出数据//4、关闭管道的读端,并退出}else if(pid>0) //父进程执行代码{//1、父进程先关闭了管道的读端//2、向管道写入字符串数据//3、关闭写端,并等待子进程结束后退出}return 0;}2、编译应用程序pipe_rw.c3、运行应用程序子进程先睡两秒让父进程先运行,父进程分两次写入“hello”和“pipe”,然后阻塞等待子进程退出,子进程醒来后读出管道里的内容并打印到屏幕上再退出,父进程捕获到子进程退出后也退出4、由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的读端和写端。
进程实验-进程间通信(管道、消息、共享内存、软中断)
进程实验3 Linux 进程间通信一、软中断信号的处理,实现同一用户的各进程之间的通信。
●相关的系统调用⏹kill(pid ,sig):发送信号⏹signal(sig, func):指定进程对信号sig的处理行为是调用函数func。
●程序清单#include <unistd.h>#include <stdio.h>#include <signal.h>void waiting();void stop();int wait_mark;main(){int p1,p2;while((p1=fork())==-1);if(p1>0){while((p2=fork())==-1);if(p2>0){ printf("parent\n");/*父进程在此完成某个操作、或接收到用户从键盘输入的特殊按键命令后发出下面的信号。
这里省略。
*/kill(p1,16);kill(p2,17);wait(0);wait(0);printf("parent process id killed! \n");exit(0);}else/* p2==0*/{printf("p2\n");wait_mark=1;signal(17,stop);waiting();printf("child process 2 is killed by parent! \n");exit(0);}}else/*p1==0*/{printf("p1\n");wait_mark=1;signal(16,stop);waiting();printf("child process 1 is kelled by parent! \n");exit(0);}}void waiting(){while(wait_mark!=0);}void stop(){wait_mark=0;}●输入并运行此程序,分析程序的运行结果。
进程通信课程设计
进程通信课程设计一、课程目标知识目标:1. 让学生掌握进程通信的基本概念,了解进程与线程的区别及通信机制。
2. 学会使用至少一种进程通信方法,如管道、消息队列、共享内存、信号量等,并理解其工作原理。
3. 掌握进程同步与互斥的概念,了解常见同步互斥机制。
技能目标:1. 培养学生运用进程通信方法解决实际问题的能力,能编写简单的进程通信程序。
2. 提高学生分析进程通信场景,选择合适通信机制的能力。
情感态度价值观目标:1. 培养学生对计算机操作系统及进程通信的兴趣,激发学生主动探索精神。
2. 培养学生具备团队协作意识,能够与同学共同完成进程通信相关的项目任务。
3. 引导学生认识到进程通信在计算机系统中的重要性,增强学生的专业认同感。
课程性质分析:本课程为计算机科学与技术专业课程,旨在让学生深入了解操作系统中进程通信的相关知识。
学生特点分析:学生已具备一定的编程基础和操作系统知识,具有较强的学习能力和动手能力。
教学要求:1. 注重理论与实践相结合,通过实例分析,让学生更好地理解和掌握进程通信技术。
2. 鼓励学生参与课堂讨论,培养学生主动思考和解决问题的能力。
3. 强化实践环节,让学生在实际操作中掌握进程通信技术,提高编程技能。
二、教学内容1. 进程通信基本概念:进程与线程的对比,进程间通信的必要性及常见通信方式。
教材章节:第二章 进程管理,第三节 进程同步与通信2. 进程通信机制:管道、消息队列、共享内存、信号量、信号等。
教材章节:第二章 进程管理,第四节 进程通信机制3. 进程同步与互斥:互斥锁、条件变量、读写锁等同步互斥机制。
教材章节:第二章 进程管理,第五节 进程同步与互斥4. 进程通信实例分析:分析具体场景,选择合适的通信机制,进行实例讲解。
教材章节:第二章 进程管理,第六节 进程通信实例5. 实践环节:编写简单的进程通信程序,加深对进程通信机制的理解。
教材章节:实验教程,实验五 进程通信编程教学进度安排:1. 基本概念与通信机制(2课时)2. 同步互斥机制(2课时)3. 实例分析(2课时)4. 实践环节(4课时)教学内容确保科学性和系统性,结合教材章节,从理论到实践,使学生全面掌握进程通信的相关知识。
进程通信的实验报告
一、实验目的1. 理解进程通信的概念和作用。
2. 掌握进程通信的常用方法,包括管道、消息队列、信号量等。
3. 通过编程实践,加深对进程通信机制的理解和应用。
二、实验环境操作系统:Linux开发环境:gcc三、实验内容1. 管道通信2. 消息队列通信3. 信号量通信四、实验步骤及分析1. 管道通信(1)实验步骤1)创建一个父进程和一个子进程;2)在父进程中创建一个管道,并将管道的读端和写端分别赋给父进程和子进程;3)在父进程中,通过管道的写端发送数据给子进程;4)在子进程中,通过管道的读端接收父进程发送的数据;5)关闭管道的读端和写端;6)结束进程。
(2)实验分析通过管道通信,实现了父进程和子进程之间的数据传递。
管道是半双工通信,数据只能单向流动。
在本实验中,父进程向子进程发送数据,子进程接收数据。
2. 消息队列通信(1)实验步骤1)创建一个消息队列;2)在父进程中,向消息队列中发送消息;3)在子进程中,从消息队列中接收消息;4)删除消息队列;5)结束进程。
(2)实验分析消息队列是一种进程间通信机制,允许不同进程之间传递消息。
消息队列的创建、发送、接收和删除等操作都是通过系统调用实现的。
在本实验中,父进程向消息队列发送消息,子进程从消息队列接收消息,实现了进程间的消息传递。
3. 信号量通信(1)实验步骤1)创建一个信号量;2)在父进程中,对信号量执行P操作,请求资源;3)在子进程中,对信号量执行V操作,释放资源;4)结束进程。
(2)实验分析信号量是一种用于实现进程同步的机制。
在进程通信中,信号量可以用来协调多个进程对共享资源的访问。
在本实验中,父进程和子进程通过信号量实现了对共享资源的同步访问。
五、实验结果1. 管道通信实验结果:父进程成功向子进程发送数据,子进程成功接收数据。
2. 消息队列通信实验结果:父进程成功向消息队列发送消息,子进程成功从消息队列接收消息。
3. 信号量通信实验结果:父进程成功获取资源,子进程成功释放资源。
实现进程间通信的实验原理
实现进程间通信的实验原理进程间通信(Inter-Process Communication,IPC)是指在操作系统中,不同的进程之间进行数据交换和共享的一种机制。
常见的进程间通信的方法有:1. 管道(Pipe):管道是一种半双工的通信机制,它可以实现父子进程之间的通信。
通常由操作系统创建,父进程创建一个管道后,可以通过fork系统调用创建子进程,从而共享管道。
子进程可以通过管道进行写入一端,父进程可以通过管道进行读取。
2. 命名管道(Named Pipe):命名管道也是一种管道,但它允许不相关的进程之间进行通信。
命名管道被创建时,通过指定一个路径名,从而使不同进程能够通过路径名来访问同一管道。
3. 信号量(Semaphore):信号量是一种计数器,用于控制多个进程对共享资源的访问。
进程可以通过特定的操作(比如P操作和V操作)来对信号量进行增加或减少操作。
同一时刻只允许一个进程对信号量进行P操作,其他进程需要等待。
4. 共享内存(Shared Memory):共享内存是一种进程之间共享数据的方式,它在物理内存中创建一块共享区域,多个进程可以将这块内存映射到各自的虚拟地址空间中。
进程可以直接读写共享内存,而无需进行数据拷贝。
5. 消息队列(Message Queue):消息队列是一种可以实现不同进程之间通过消息进行通信的机制。
进程可以通过特定的操作将消息发送到消息队列中,其他进程可以从消息队列中读取消息。
6. 套接字(Socket):套接字是一种网络编程中常用的进程间通信方式。
它可以在不同主机上的进程之间进行通信。
进程可以通过套接字进行网络数据的读取和写入。
以上是常见的几种进程间通信的方法,每种方法都有自己的优势和适用场景。
根据具体的需求,可以选择适合的方式进行进程间通信。
进程之间的通信实验
实验:进程之间的通信管道1.Pipe函数与进程通信下面实验为使用管道进行父子进程间通信。
程序首先判断参数是否合法,因为输入的字符将从父进程通过发送到子进程中。
然后,调用pipe函数创建父子进程用于通信的管道。
使用fork函数创建子进程时,子进程会获得与父进程相同的资源,其中包括文件描述符信息。
因此,调用fork函数须在pipe函数调用前。
当父子进程通过管道进行通信时,files[1]为用于数据写入的文件描述符.因此,在子进程中,要读取管道中的数据可以调用read函数,而读取得文件描述符为files[0]。
对于父进程而言,写入数据需要调用write 函数,要写入的文件描述为files[1]。
#include <stdio.h>#include <unistd.h>int main(int argc,char* argv[]){int f_des[2];int pid;char msg[BUFSIZ];if(argc!=2){printf("Usage: %s message\n",argv[0]);return 1;}if(pipe(f_des)==-1){perror("cannot create the IPC pipe");return 1;}pid=fork();if(pid==-1){perror("cannot create new process");return 1;}else if(pid==0){close(f_des[1]);if(read(f_des[0],msg,BUFSIZ)==-1){perror("child process cannot read data from pipe");return 1;}elseprintf("in child process, receive message: %s\n",msg);_exit(0);}else {close(f_des[0]);if(write(f_des[1],argv[1],strlen(argv[1]))==-1){perror("parent process cannot write data to pipe");return 1;}elseprintf("in parent process, send message: %s\n",argv[1]);wait(NULL);_exit(0);}return 0;}2. Shell管道重订向的实现实现了在SHELL中的两个命令的组合。
操作系统实验报告 进程间通信
《计算机操作系统》实验报告(二)学号:030702412 姓名:陈楠学院:数计学院专业:计算机类年级:2007级班级:4班实验时间:2009-2010学年第一学期指导教师:丁善镜、黄志华目录1、实验题目 (3)2、实验目的 (3)3、实验环境 (3)4、实验原理 (3)5、实验内容 (3)5.1、fork()函数机理探索...........................................................错误!未定义书签。
5.1.1、原始代码段................................................................错误!未定义书签。
5.1.2、代码段修改一............................................................错误!未定义书签。
5.1.3、结论(1) .......................................................................错误!未定义书签。
5.1.4、fock()函数原理...........................................................错误!未定义书签。
5.1.5、代码段修改二............................................................错误!未定义书签。
5.2、并发执行测猜测................................................................错误!未定义书签。
5.2.1、并发执行改进............................................................错误!未定义书签。
1026-S15.进程间通信实验
进程间通信实验一、设计目的配合嵌入式操作系统 WinCE 课程的学习,通过对消息传递和共享内存的实现,加深对 WinCE5.0 下进程间通信机制的理解。
二、设计内容在客户端(Client 端)使用 SendMessage函数发送消息到服务器端(Server 端)或通过 使用内存映像机制实现进程间通信。
在 msgclient 的编辑框中输入字符串,点击 SendMessage,可以将信息发送到 msgserver 程序的“接收到”编辑框中。
这是采用WM_COPYDATA机制。
在 msgclient 的编辑框中输入字符串,点击 SendToMem,可以将信息发送到 msgserver 程序的“接收历史”多行编辑框中。
这是采用 FileMapping机制。
三、开发环境Visual Studio 2005 及 WinCE5_ARM_Emulator 模拟器四、设计原理由于 WinCE 采用内存保护机制,不允许一个进程访问其它进程的地址空间。
但是由于进程间存在共享数据的需要,因此操作系统提供了一种机制,可以把一个进程地址空间中的 数据复制到另外一个进程的地址空间中。
常见通信方式:剪贴板(Clipboard) 、COM/DCOM、网络套接字(Socket)、 WM_COPYDA TA消息。
在 Win32 中,WM_COPYDA TA 消息主要目的是允许在进程间传递只读数据。
SDK 文 档推荐用户使用 SendMessage()函数,接收方在数据复制完成前不返回,这样发送方就不可 能删除和修改数据。
这个函数的原型如下:SendMessage(WM_COPYDA TA,wParam, lParam);其中 wParam设置为包含数据的窗口句柄,lParam指向一个 COPYDA TASTRUCT 的结 构,其定义为:typedef struct tagCOPYDATASTRUCT{DWORD dwData;DWORD cbData;PVOID lpData;}COPYDA TASTRUCT;其中 dwData 为自定义数据, cbData 为数据大小, lpData 为指向数据的指针。
实验五_Linux进程间通信
实验五 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)共享同一个管道进行通信的读写进程之间必须满足什么关系,为什么?。
实验五-进程间通信
实验五进程间通信UNIX/LINUX系统的进程间通信机构(IPC)允许在任意进程间大批量地交换数据。
本实验的目的是了解和熟悉LINUX支持的信号机制、管道机制、消息队列通信机制及共享存储区机制。
5.1信号机制实验(一)【实验目的】1.了解什么是信号。
2.熟悉LINUX系统中进程之间软中断通信的基本原理。
【实验原理】利用signal来实现发送信号和接受信号的原理【实验内容】1.编写一段程序,使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到父进程发来的信号后,分别输出下列信息后终止:Child process 1 is killed by parent!Child process 2 is killed by parent!父进程等待两个子进程终止后,输出以下信息后终止:Parent process is killed!<参考程序># include<stdio.h># include<signal.h># include<unistd.h>int wait_mark;void waiting(),sto p();void main(){ int p1, p2;signal(SIGINT,stop);while((p1=fork())==-1);if(p1>0) /*在父进程中*/{ ①while((p2=fork())= =-1);If(p2>0) /*在父进程中*/{ ②wait_mark=1;waiting(0);kill(p1,10);kill(p2,12);wait( );wait( );printf(“parent process is killed!\n”);exit(0);}else /*在子进程2中*/{wait_mark=1;signal(12,stop);waiting();lockf(1,1,0);printf(“child process 2 is killed by parent!\n”);lockf(1,0,0);exit(0);}}else /*在子进程1中*/{wait_mark=1;signal(10,stop);waiting();lockf(1,1,0);printf(“child process 1 is killed by parent!\n”);lockf(1,0,0);exit(0);}}void waiting(){while(wait_mark!=0);}void stop(){wait_mark=0;}实验要求:⑴运行程序并分析结果。
实验四进程间通信(信号量机制实验)
2021/6/12
3
5、信号的安装(设置信号关联动作)
系统调用格式:
signal( sig , function )
参数定义:
int sig;
void (*function)( );
函数说明:当指定信号sig 到达时就会跳转到 function指定的函数执行。如果参function 不是函数指针,则必须是下列两个常数之一:
int kill(pid,sig) 参数定义
int pid,sig; 其中,pid是一个或一组进程的标识符, 参数sig是要发送的软中断信号。
2021/6/12
2
4、进程对信号的响应 进程可以通过三种方式来响应一个信号: ⑴忽略信号
对信号不做任何处理; ⑵捕捉信号
定义信号处理函数,当信号发生时,执 行相应的处理函数; ⑶执行缺省操作
signal(10,stop)中的10是用户自定义的信 号,由父进程发出。父进程用kill(p1,10 ) 函数发中断信号10给子进程p1,子进程p1 在收到父进程发来的中断信号10时,就转 入stop( )做相应处理。
2021/6/12
5
用于科普,若有不 当之处,请指正,感
谢您的下载。
2021/6/12
SIG_IGN 忽略参数sig指定的信号 (SIG_INT=1)
SIG_DFL 将参数sig 指定的信号重设为核心
预设的信号处理方式。(SIG_Fra bibliotekFL=0)2021/6/12
4
例如:signal( SIGINT, stop)中的SIGINT 是来自键盘的中断信号,当键盘有中断信 号产生时,进程就会转入stop( ) 做相应处 理。
实验五 进程间通信 (信号量机制实验) 1、信号
进程通信实验报告
进程通信实验报告进程通信实验报告概述进程通信是操作系统中非常重要的一个概念,它允许不同的进程之间进行数据的交换和共享。
在本次实验中,我们通过使用不同的进程通信机制,如管道、消息队列和共享内存,来实现进程之间的数据传输和通信。
本报告将详细介绍实验的背景、实验过程、结果分析以及对实验的总结。
实验背景进程通信是操作系统中的一个核心概念,它允许多个进程之间进行数据的交换和共享。
在现代操作系统中,进程通信是实现并发和协作的重要手段。
了解不同的进程通信机制以及它们的优缺点对于深入理解操作系统的原理和实现至关重要。
实验过程在本次实验中,我们使用了三种不同的进程通信机制:管道、消息队列和共享内存。
首先,我们创建了两个进程,一个作为发送方,一个作为接收方。
然后,我们分别使用了管道、消息队列和共享内存来实现进程之间的数据传输和通信。
管道是一种最简单的进程通信机制,它可以在父进程和子进程之间进行单向的通信。
我们通过创建一个管道,并将其连接到父进程和子进程的标准输入和标准输出,实现了父子进程之间的数据传输。
消息队列是一种更为灵活的进程通信机制,它可以实现多个进程之间的双向通信。
我们使用了系统提供的消息队列函数,创建了一个消息队列,并在发送方将消息发送到队列中,接收方则从队列中接收消息。
通过消息队列,我们实现了进程之间的异步通信。
共享内存是一种高效的进程通信机制,它允许多个进程共享同一块内存空间。
我们使用了共享内存函数,创建了一个共享内存区域,并将其映射到两个进程的虚拟地址空间中。
通过共享内存,我们实现了进程之间的数据共享和同步。
结果分析通过实验,我们发现不同的进程通信机制各有优缺点。
管道是最简单的一种机制,但只能实现单向通信,且只能用于具有亲缘关系的进程。
消息队列可以实现多个进程之间的双向通信,但消息的顺序可能会被打乱。
共享内存是最高效的一种机制,但需要额外的同步机制来保证数据的一致性。
总结进程通信是操作系统中非常重要的一个概念,它允许不同的进程之间进行数据的交换和共享。
进程间通信实验资料
进程间通信(1)调试以下程序给出运行结果并分析其程序原理:#include <stdio.h>#include <unistd.h>#include <wait.h>#include <signal.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>(1)编写两个程实现进程的无名管道和有名管道通信。
要求分别调用pipe()、close()、write()、read()、popen()、pclose()、mknod()、mkfifo()、open()实现多个进程间的通信。
1.使用无名管道pipe(),进行父子进程之间的通信。
编写的程序如下:fork函数执行完毕后,返回值pid<0,则子进程创建失败,pid>0,则运行父进程,关闭读操作,进行写操作,将信息写进管道,写完后关闭写操作,父进程挂起。
Pid=0,运行子程序,关闭写操作,进行读操作,读完信息关闭读操作,子进程运行结束,父进程继续运行。
2.以命名行为参数的管道文件的示例。
(假设有一个可执行程序chcase,从标准输入设备读字符,将小写字母转化成大写字母并输出。
主程序使用popen创建管道,实现蒋某文本文件中的字幕转化成大写字母,其中的文本文件名作为参数传进来。
)命令行数量不为2时,输出结果如图所示;创建一个可执行程序chcase,此程序从标准输入设备读字符,将小写字母转化成大写字母并输出。
主程序使用popen()创建一个管道。
再创建一个文本文件,输入将要转换成大写字母的小写字母。
Popen创建的管道一头与文本文件相连,获取文本文件中的信息,将此信息通过管道传送给与管道另一端相连的可执行程序chcase,chcase获取文本文件中的小写字母后,将小写字母转换成大写字母输出。
实验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”为止。
实验五 Linux进程间通信05010501
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); } } } 实验要求:运行程序并分析结果,将上面程序修改成,在父进程中用 pipe()建立一条管道, 往管道里写字符串,两个子进程分别接收父进程往管道里写的字符串。
lockf(fd[1],1,0); sprintf(OutPipe, "child 1 process is sending message!"); write(fd[1],OutPipe,50); sleep(5); lockf(fd[1],0,0); exit(0); } else{
while((pid2=fork())== -1); if(pid2 == 0) {
//printf("child2 exit status is %d\n", WEXITSTATUS(status2));
printf("parent process is killed!\n");
exit(0);
} else{
/*在子进程 2 中*/
wait_mark=1; signal(12,stop); //捕捉到中断信号 12 后,调用 stop 函数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验五:进程间通信●实验目的:学会进程间通信方式:无名管道,有名管道,信号,共享内存●实验要求:(一)在父进程中创建一无名管道,并创建子进程来读该管道,父进程来写该管道(二)在进程中为SIGBUS注册处理函数,并向该进程发送SIGBUS信号(三)创建一共享内存,实现放进程间通信●实验器材:软件:安装了Linux的vmware虚拟机硬件:PC机一台●实验步骤:(一)无名管道的使用1、编写实验代码pipe_rw.c#include <unistd.h>#include <sys/types.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <stdlib.h>int 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));/*创建管道*/if(pipe(pipe_fd)<0){printf("pipe create error\n");return -1;}/*创建子进程*/if((pid=fork())==0) //子进程执行代码{//1、子进程先关闭了管道的写端//2、让父进程先运行,这样父进程先写子进程才有内容读//3、读取管道的读端,并输出数据//4、关闭管道的读端,并退出}else if(pid>0) //父进程执行代码{//1、父进程先关闭了管道的读端//2、向管道写入字符串数据//3、关闭写端,并等待子进程结束后退出}return 0;}2、编译应用程序pipe_rw.c3、运行应用程序子进程先睡两秒让父进程先运行,父进程分两次写入“hello”和“pipe”,然后阻塞等待子进程退出,子进程醒来后读出管道里的内容并打印到屏幕上再退出,父进程捕获到子进程退出后也退出4、由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的读端和写端。
我们往往希望父子进程中的一个进程写一个进程读,那么写的进程最后关掉读端,读的进程最好关闭掉写端(二)信号处理1、编写实验代码sig_bus.c#include <signal.h>#include <stdio.h>#include <stdlib.h>//1、自定义信号处理函数,处理SIGBUS信号,打印捕捉到信号即可int main(){printf("Waiting for signal SIGBUS \n ");//2、注册信号处理函数pause();//将进程挂起直到捕捉到信号为止exit(0);}用signal系统调用为SIGBUS信号注册信号处理函数my_func,然后将进程挂起等待SIGBUS信号。
所以需要向该进程发送SIGBUS信号才会执行自定义的信号处理函数2、编译应用程序sig_bus.c3、运行应用程序先先一个终端中运行sig_bus,会看到进程挂起,等待信号然后在另一个终端中,查找到运行sig_bus这个产生的进程号,用kill命令发送SIGBUS信号给这个进程我们可以看到前面挂起的进程在接收到这个信号后的处理用自定义信号处理函数my_func来处理,所以打印了I have get SIGBUS这样一句话(三)共享内存1、本实验利用共享内存完成两个进程之间的通信,发送端的消息类型设置为该进程的进程号(可以取其他值),接收端接收消息(类似消息队列的功能),这里同时需要采用信号量为同步机制完善两个进程间的通信。
2、下面是共享内存缓冲区的数据结构的定义/* shm_com.h */#ifndef SHM_COM_H#define SHM_COM_H#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#define SHM_BUFF_SZ 2048struct shm_buff{int pid;char buffer[SHM_BUFF_SZ];};#endif /* SHM_COM_H */以下是发送端的部分程序,请完善信号量的操作代码/* producer.c */#include "shm_com.h"#include <signal.h>int ignore_signal(void){signal(SIGINT, SIG_IGN);signal(SIGSTOP, SIG_IGN);signal(SIGQUIT, SIG_IGN);return 0;}int main(){void *shared_memory = NULL;struct shm_buff *shm_buff_inst;char buffer[BUFSIZ];int shmid, semid;ignore_signal(); /* 防止程序非正常退出*//* 创建一个信号量*//* 初始值为1 *//* 创建共享内存*/shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);if (shmid == -1){perror("shmget failed");//删除信号量exit(1);}/* 将共享内存地址映射到当前进程地址空间*/shared_memory = shmat(shmid, (void*)0, 0);if (shared_memory == (void*)-1){perror("shmat");//删除信号量exit(1);}printf("Memory attached at %X\n", (int)shared_memory);/* 获得共享内存的映射地址*/shm_buff_inst = (struct shm_buff *)shared_memory;do{printf("Enter some text to the shared memory(enter 'quit' to exit):");/* 向共享内存写入数据*/if (fgets(shm_buff_inst->buffer, SHM_BUFF_SZ, stdin) == NULL){perror("fgets");sem_v(semid);break;}shm_buff_inst->pid = getpid();} while(strncmp(shm_buff_inst->buffer, "quit", 4) != 0);/* 删除信号量*//* 删除共享内存到当前进程地址空间中的映射*/if (shmdt(shared_memory) == 1){perror("shmdt");exit(1);}exit(0);}以下是接收端程序部分,请完善信号量操作的代码/* customer.c */#include "shm_com.h"int main(){void *shared_memory = NULL;struct shm_buff *shm_buff_inst;int shmid, semid;/* 获得信号量*//* 获得共享内存*/shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);if (shmid == -1){perror("shmget");exit(1);}/* 将共享内存地址映射到当前进程地址空间*/shared_memory = shmat(shmid, (void*)0, 0);if (shared_memory == (void*)-1){perror("shmat");exit(1);}printf("Memory attached at %X\n", (int)shared_memory);/* 获得共享内存的映射地址*/shm_buff_inst = (struct shm_buff *)shared_memory;do{printf("Shared memory was written by process %d :%s", shm_buff_inst->pid, shm_buff_inst->buffer);if (strncmp(shm_buff_inst->buffer, "quit", 4) == 0){break;}shm_buff_inst->pid = 0;memset(shm_buff_inst->buffer, 0, SHM_BUFF_SZ);} while(1);/* 删除共享内存到当前进程地址空间中的映射*/if (shmdt(shared_memory) == -1){perror("shmdt");exit(1);}/* 删除共享内存*/if (shmctl(shmid, IPC_RMID, NULL) == -1){perror("shmctl(IPC_RMID)");exit(1);}exit(0);}3、实验结果上机报告要求:1、总结pipe(),signal(),shmget()函数定义原型,返回值和参数的意义2、利用有名管道FIFO实现类似第一个实验的功能,一个程序fifo_read.c写数据”Hi Linux”,另一个程序fifo_write.c读数据并打印出来。