Linux进程间通信(2)实验报告
进程间通信实验报告
软件学院计算机课程实验报告册课程名称计算机操作系统实验学期 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进程间通信
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); }
指导教师评语:
《嵌入式操作系统应用开发》 课程实验报告
班 级: 学 号: 姓 名: 指导老师: 成 绩:
实验九:System V 进程间通信
一、目的与任务 目的:了解掌握操作系统消息队列、信号量的特点与功能,学会借助消息队
列、信号量的功能函数进行编程。 任务:利用 C 语言指令编写程序调用消息队列、信号量函数,完成相应功
(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>
} msqid = msgget(key,IPC_CREAT | IPC_EXCL | 0644); if(msqid == -1){
perror("msgget failed"); exit(2); } return 0; }
《Linux操作系统设计实践》实验二:进程通信
《Linux操作系统设计实践》实验二:进程通信实验目的:进一步了解和熟悉 Linux 支持的多种 IPC 机制,包括信号,管道,消息队列,信号量,共享内存。
实验环境: redhat实验内容:(1)进程间命名管道通信机制的使用:使用命名管道机制编写程序实现两个进程间的发送接收信息。
(2)进程间消息队列通信机制的使用:使用消息队列机制自行编制有一定长度的消息(1k 左右)的发送和接收程序。
(3)进程间共享存储区通信机制的使用:使用共享内存机制编制一个与上述(2)功能相同的程序。
并比较分析与其运行的快慢。
实验代码验证:(1).使用命名管道机制编写程序实现两个进程间的发送接收信息。
#include <stdio.h>#include <stdlib.h>#define FIFO_FILE "MYFIFO"int main(int argc, char *argv[]){FILE *fp;int i;if (argc<=1){printf("usage: %s <pathname>\n",argv[0]); exit(1);}if ((fp = fopen(FIFO_FILE, "w")) == NULL) {printf("open fifo failed. \n");exit(1);}for (i = 1; i < argc; i++){if (fputs(argv[i],fp) == EOF){printf("write fifo error. \n");exit(1);}if (fputs(" ",fp) == EOF){printf("write fifo error. \n"); exit(1);}}fclose(fp);return 0;}#include <stdio.h>#include <stdlib.h>#include <sys/stat.h>#include <unistd.h>#include <linux/stat.h>#define FIFO_FILE "MYFIFO"int main(){FILE *fp;char readbuf[80];if ((fp = fopen(FIFO_FILE, "r")) == NULL) {umask(0);mknod(FIFO_FILE, S_IFIFO | 0666, 0);}else{fclose(fp);}while (1){if ((fp = fopen(FIFO_FILE, "r")) == NULL) {printf("open fifo failed. \n");exit(1);}if (fgets(readbuf, 80, fp) != NULL){printf("Received string :%s \n", readbuf); fclose(fp);}else{if (ferror(fp)){printf("read fifo failed.\n");exit(1);}}}return 0;}实验结果:Server.c将client.c写入的字符输出。
实验二 进程间通讯 实验报告
Linux信号量实验报告一、实验目的深入理解操作系统中进程间通讯的本质二、实验方法利用UNIX/LINUX所提供的信号量、共享存储器、PV操作、文件锁等机制实现进程间的信息共享、进程间的互斥与同步。
三、实验任务编写一个C语言程序,该程序将一个存放了一个整数的文本文件内容执行加1操作一百万次,同时启动这个程序的多个副本,观察执行结果是否正确。
利用信号量机制对文件上锁,重新运行观察结果是否正确。
四、实验要点信号量概念、PV操作五、实验内容5.1 信号量概念信号量是一种确保特定代码段(临界区)只能被一个进程或者线程调用的一种机制。
在实际应用中,信号量由一种特殊的数据结构——信号量集所管理。
在使用信号量以前,需要创建一个信号量集,使用完成以后需要销毁信号量集。
信号量集的作用相当于一个信号量的计数器。
P操作是向信号量集获取一个信号量的操作,如果此时信号量集中有信号量,则会对信号量中的计数器进行更改(大部分情况下是计数器减一);如果此时信号量集中没有可用信号量(即计数器为0时),则执行P操作的线程或者进程则会被阻塞,直到信号量集中拥有可用的信号量(即计数器不为0)。
具体关系可用下图表示:5.2 信号量的初始化信号量的初始化需要用到两个函数(semget和semctl)和一个联合体结构(该实验中我们只需要用联合体结构中的val值,所以我只定义val变量)。
Semget系统调用的定义如下:int semget(key_t key, int nsems, int semflg)semget这个系统调用的作用是返回一个与key参数相关联的一个信号量集标识,semflg 参数会控制函数的行为;如果semflg为IPC_CREAT或者IPC_PRIVATE,则函数会创建一个拥有nsems个信号量的信号量集;如果semflg的值为IPC_CREAT | IPC_EXCL,在信号量集已经存在的情况下会发生错误。
实验中使用的获得信号量集标识的代码为:int sem_id = semget((key_t)2234, 0, 0);if (sem_id == -1){sem_id = semget((key_t)2234, 1, 0666 | IPC_CREAT);if (!init(sem_id)) return -1;}上述代码的第一行,nsems和semflg参数均为0,目的是只获得与2234这个值相关联的信号量集的标识;如果这个信号量集已经存在,则返回这个信号量集的标识;否则返回-1 下面就对获得的sem_id进行判断,如果值为-1,即信号量集还没有被创建,需要创建一个信号量集。
实验二 Linux进程通信
实验二 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,并显示出来。
试验二进程通信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开发环境: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. 信号量通信实验结果:父进程成功获取资源,子进程成功释放资源。
进程通讯管理实验报告(3篇)
第1篇一、实验目的1. 理解进程通信的概念和原理;2. 掌握进程通信的常用机制和方法;3. 能够使用进程通信机制实现进程间的数据交换和同步;4. 增强对操作系统进程管理模块的理解。
二、实验环境1. 操作系统:Linux2. 编程语言:C3. 开发环境:GCC三、实验内容1. 进程间通信的管道机制2. 进程间通信的信号量机制3. 进程间通信的共享内存机制4. 进程间通信的消息队列机制四、实验步骤1. 管道机制(1)创建管道:使用pipe()函数创建管道,将管道文件描述符存储在两个变量中,分别用于读和写。
(2)创建进程:使用fork()函数创建子进程,实现父子进程间的通信。
(3)管道读写:在父进程中,使用read()函数读取子进程写入的数据;在子进程中,使用write()函数将数据写入管道。
(4)关闭管道:在管道读写结束后,关闭对应的管道文件描述符。
2. 信号量机制(1)创建信号量:使用sem_open()函数创建信号量,并初始化为1。
(2)获取信号量:使用sem_wait()函数获取信号量,实现进程同步。
(3)释放信号量:使用sem_post()函数释放信号量,实现进程同步。
(4)关闭信号量:使用sem_close()函数关闭信号量。
3. 共享内存机制(1)创建共享内存:使用mmap()函数创建共享内存区域,并初始化数据。
(2)映射共享内存:在父进程和子进程中,使用mmap()函数映射共享内存区域。
(3)读写共享内存:在父进程和子进程中,通过指针访问共享内存区域,实现数据交换。
(4)解除映射:在管道读写结束后,使用munmap()函数解除映射。
4. 消息队列机制(1)创建消息队列:使用msgget()函数创建消息队列,并初始化消息队列属性。
(2)发送消息:使用msgsnd()函数向消息队列发送消息。
(3)接收消息:使用msgrcv()函数从消息队列接收消息。
(4)删除消息队列:使用msgctl()函数删除消息队列。
实验二进程通信 Linux实验报告
实验报告学号_____ 姓名____ ___ 成绩实验二进程通信【实验目的和要求】1、了解进程通信的概念及方法;2、了解信号量、管道;3、掌握信号量、管道和命名管道编程方法。
【实验内容】1、利用命名管道实现单机QQ聊天;2、撰写实验报告;【实验原理】1、信号量(semaphore)是为那些访问相同资源的进程以及同一进程不同线程之间提供的一个同步机制。
它不是用于传输数据,而只是简单地协调对共享资源的访问。
信号量包含一个计数器,表示某个资源正在被访问和访问的次数,用来控制多进程对共享数据的访问。
一旦成功拥有了一个信号量,对它所能做的操作只有两种:请求和释放。
当执行释放操作时,系统将该信号值减1(如果小于零,则设置为零);当执行请求操作时,系统将该信号值加1,如果加1后的值大于设定的最大值,那么系统将会挂起处理进程,直到信号值小于最大值为止。
Tuxedo 用信号量来确保在某一时刻只有一个进程对某一块共享内存进程访问。
信号量配置太低会导致Tuxedo系统应用程序无法启动。
2、管道分为两种:管道和命名管道。
管道是UNIX系统IPC的最古老形式,并且所有的UNIX系统都提供这种通信机制。
可以在有亲缘关系(父子进程或者是兄弟进程之间)进行通信,管道的数据只能单向流动,如果想双向流动,必须创建两个管道。
管道应用的一个重大缺陷就是没有名字,因此只能用于亲缘进程之间的通信。
后来以管道为基础提出命名管道(named pipe,FIFO)的概念,该限制得到了克服。
FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。
这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。
值得注意的是,FIFO严格遵循先进先出(first in first out)规则,对管道及FIFO的读总是从开始处返回数据,对它们的写则是把数据添加到末尾。
实验三2_Linux进程间通信
实验三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()函数十分相似,用法也相同。
Linux进程通信实验报告
三、 实验环境
一台安装了 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;}Leabharlann }Linux 进程通信实验报告
操作系统实验报告_Linux进程创建与通信
2011-2012学年第一学期计算机操作系统实验报告专业:班级:学号:姓名:提交日期:2011年11月1实验二Linux进程创建与进程通信【实验目的】1. 熟悉有关Linux系统调用;2. 学习有关Linux的进程创建,理解进程创建后两个并发进程的执行;3. 通过系统调用wait()和exit(),实现父子进程同步;4. 掌握管道、消息缓冲等进程通信方法并了解其特点和使用限制。
【实验内容】1. 父进程创建子进程实现父进程创建一个子进程,返回后父子进程分别循环输出字符串“The parent process.”及“The child process.”5次,每次输出后使用sleep(1)延时一秒,然后再进入下一次循环。
给出源程序代码和运行结果。
程序代码:main(){int p1,i;while ((p1=fork())==-1);if (p1>0)for (i=0;i<5;i++){printf("I am parent.\n");sleep(1);}elsefor (i=0;i<5;i++){printf("I am child.\n");sleep(1);}}运行结果:The parent process.The child process.The parent process.The child process.The parent process.The child process.The parent process.The child process.The parent process.The child process.2. 父子进程同步修改上题程序,使用exit()和wait()实现父子进程同步,其同步方式为父进程等待子进程的同步,即:子进程循环输出5次,然后父进程再循环输出5次。
给出源程序代码和运行结果。
程序代码:main(){int p1,i;while ((p1=fork())==-1);if (p1>0){wait(0);for (i=0;i<5;i++){printf("I am parent.\n");sleep(1);}}else{for (i=0;i<5;i++){printf("I am child.\n");sleep(1);}exit(0);}}运行结果:I am parent.I am parent.I am parent.I am parent.I am parent.I am child.I am child.I am child.I am child.I am child.3. Linux管道通信编写一个程序,实现以下功能。
实验二 Linux进程间通信
实验二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!而父进程则循环从管道中读出信息,显示在屏幕上。
实验四、进程通信(二) ——消息通信
操作系统实验报告实验四、进程通信(二)——消息通信一、实验目的1)加深对管道通信的了解2)掌握利用管道进行通信的程序设计3)了解共享内存通信的程序设计方法4)了解和熟悉Linux支持的共享存储区机制二、实验内容任务:(1)每个同学登陆两个窗口,先在一个窗口中运行程序1(或者只登陆一个窗口,先在该窗口中以后台方式运行程序1),用ipcs命令查看系统中消息队列的情况,然后在另一个窗口中运行程序2,观察程序的运行结果并分析。
运行结束后可以用ctrl+c结束程序1的运行,再次用ipcs命令观察系统中消息队列的情况。
(2)使用系统调用msgget(),msgsnd(),msgrev()及msgctl()编制一长度为1K的消息的发送和接收程序。
①为了便于操作和观察结果,用一个程序作为“引子”,先后fork()两个子进程,SERVER和CLIENT,进行通信。
②SERVER端建立一个Key为学号末3位的消息队列,等待其他进程发来的消息。
当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER。
SERVER每接收到一个消息后显示一句“(server)received”。
③CLIENT端使用key为学号末3位的消息队列,先后发送类型从10到1的消息,然后退出。
最后的一个消息,即是SERVER端需要的结束信号。
CLIENT 每发送一条消息后显示一句“(client)sent”。
④父进程在SERVER和CLIENT均退出后结束。
三、代码及运行结果分析(1)每个同学登陆两个窗口,先在一个窗口中运行程序1(或者只登陆一个窗口,先在该窗口中以后台方式运行程序1),用ipcs命令查看系统中消息队列的情况,然后在另一个窗口中运行程序2,观察程序的运行结果并分析。
运行结束后可以用ctrl+c结束程序1的运行,再次用ipcs命令观察系统中消息队列的情况先在一个窗口中运行程序1程序1实验代码:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#define MSGKEY 208 /*在实际实验过程中,为了避免每个同学建立的消息队列关键字一样而相互干扰,关键字请用学号末3位*/struct msgform{long mtype;char mtext [256];}msg;int msgqid;main (){int i ,pid, *pint;extern cleanup();for (i=0;i<20;i++)/*软中断处理*/signal (i,cleanup);msgqid = msgget (MSGKEY,0777|IPC_CREAT);/*建立与顾客进程相同的消息队列*/ for (;;){msgrcv (msgqid ,&msg,256,1,0);/*接收来自顾客进程的消息*/pint=(int * ) msg. mtext;pid = * pint;printf ("server:receive from pid %d\n",pid);msg.mtype=pid;*pint=getpid();msgsnd (msgqid,&msg ,sizeof (int) ,0) ;/*发送应答消息*/}}cleanup(){msgctl (msgqid ,IPC_RMID,0);exit();}运行结果:ipcs命令查看在另一个窗口中运行程序2程序2实验代码:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#define MSGKEY 208 /*在实际实验过程中,为了避免每个同学建立的消息队列关键字一样而相互干扰,关键字请用学号末3位*/struct msgform{long mtype;char mtext [256];};main(){struct msgform msg;int msgqid,pid, *pint;msgqid=msgget(MSGKEY,0777);/*建立消息队列*/pid=getpid();pint=(int *)msg.mtext;*pint=pid;msg.mtype=1;/*指定消息类型*/msgsnd(msgqid,&msg,sizeof(int),0);/*往msgqid发送消息msg*/msgrcv(msgqid,&msg,256,pid,0);/*接收来自服务进程的消息*/printf("client : receive from pid%d\n",*pint);}运行结果:再次用ipcs命令观察系统中消息队列的情况分析:调用pipe(fd);创建一个管道后,接着调用fork()函数产生两个进程,首先开始执行子进程,关闭管道出口,通过管道入口向管道中写入内容。
实验二 进程通信实验
实验二进程通信实验1.实验内容设有二元函数f(x,y) = f(x) + f(y)其中:f(x) = f(x-1) * x (x >1)f(x)=1 (x=1)f(y) = f(y-1) + f(y-2) (y> 2)f(y)=1 (y=1,2)请编程建立3 个并发协作进程,它们分别完成f(x,y)、f(x)、f(y) 2.实验代码(附件中)3.在当前目录中建立Makefile文件5.使用make命令编译连接生成可执行文件pipetest6.编译成功后执行pipetest7实验要求(1)进程协作:系统中一个进程能影响其他进程或被其他进程所影响,那么该进程是协作的。
在该实验中,子进程x和子进程y 需要来自父进程传输的自变量x和y,而父进程的完成需要来自子进程x和子进程y的计算结果f(x)和f(y),所以父进程和两个子进程是协作的。
协作进程需要一种进程间通信机制来允许进程相互交换数据与信息。
(2)在实验中采用管道通信,管道是一个单向通信信道,如果进程间要进行双向通信,通常需要定义两个管道。
管道通过系统调用read(), write()函数进行读写操作。
管道通信机制的机理:一种半双工的通信机制,两个进程可以通过管道一个在管道一端向管道发送其输出,给另一进程可以在管道的另一端从管道得到其输入;另外,管道只能用来在具有公共祖先的两个进程之间通信。
管道通信遵循先进先出的原理,并且数据只能被读取一次,当此段数据被读取后,马上会从数据中消失,当管道中的数据被读取后,管道为空,一个随后的read()调用将默认的被阻塞,并等待某些数据写入。
通常会先调用pipe(),然后调用fork(),从而创建从父进程到子进程的IPC通道.。
嵌入式Linux多进程通讯实验报告
实验报告实验题目嵌入式Linux多进程通讯实验姓名:学号:课程名称:所在学院:专业班级:任课教师:实验项目名称嵌入式Linux多进程通讯实验一、实验目的与要求:1、熟悉UNIX/LINUX 支持的无名管道通信方式。
2、熟悉UNIX/LINUX 支持的有名管道通信方式。
3、熟悉 LINUX 系统中进程之间信号通信的基本原理。
4、熟悉UNIX/LINUX 支持的共享内存通信方式。
5、熟悉UNIX/LINUX 支持的消息队列通信方式。
二、实验设备:华清远见开发环境,PC机三、实验方法(原理,流程图)Linux 下的进程通信手段基本上是从 Unix 平台上的进程通信手段继承而来的。
而对 Unix 发展做出重大贡献的两大主力 AT&T 的贝尔实验室及 BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间的通信方面的侧重点有所不同。
前者是对 Unix 早期的进程间通信手段进行了系统的改进和扩充,形成了“system V IPC”,其通信进程主要局限在单个计算机内;后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制。
而 Linux 则把两者的优势都继承了下来,如图1所示。
●Unix 进程间通信(IPC)方式包括管道、FIFO 以及信号。
●System V 进程间通信(IPC)包括 System V 消息队列、System V 信号量以及 System V 共享内存区。
●Posix 进程间通信(IPC)包括 Posix 消息队列、Posix 信号量以及 Posix共享内存区。
现在在 Linux 中使用较多的进程间通信方式主要有以下几种。
图1进程间通信发展历程(1)管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。
(2)信号(Signal):信号是在软件层次上对中断机制的一种模拟,它是比较复杂的通信方式,用于通知进程有某事件发生,一个进程收到一个信号与处理器收到一个中断请求效果上可以说是一样的。
操作系统实验报告2-进程间通信
1.了解Linux中的信号,熟悉Linux系统中进程之间软中断通信的基本原理。
2.Linux系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据,学习如何利用消息缓冲队列进行进程间的通信,并加深对消息通信机制的理解。
二、实验环境(实验设备)
Windows 2000 + VMWare +RedHatLinux8
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*/
signal(17,stop); /*接收到软中断信号17,转stop*/
waiting( );
lockf(stdout,1,0);
printf("Child process 2 is killed by parent!\n");
Linux实验报告 (2)【范本模板】
Linux实验报告姓名黄芳恺班级软件工程114学号119074258指导教师阮越目录实验一 Linux基本命令的使用实验二简单Shell程序设计实验三 Linux下简单C程序设计与文件操作实验四 Linux下进程操作与进程间通信实验五 Linux线程的使用实验六 Linux进程间的IPC实验七 Linux下访问Mysql数据库实验八 Linux下网络编程练习题:grep、bash、生产者消费者实验一 Linux基本命令的使用1、实验目的学习和掌握Linux的基本命令。
2、实验内容和步骤步骤1:以user_login用户身份并使用telnet登录Linux服务器,按照提示创建自己的账户和口令。
步骤 2:使用新创建的用户账户和口令登录Linux系统,察看登录后的界面。
步骤3:使用pwd命令察看当前的工作目录,然后用ls命令查看当前目录下的内容,尝试使用-a,—l,—F,—A,-lF等不同选项并比较不同之处。
-a do not ignore entries starting with—I, --ignore=PATTERN do not list implied entries matching shell PATTERN —l use a long listing format—F,—-classify append indicator (one of */=〉@|) to entries-A,—-almost-all do not list implied 。
and 。
—lF ignore file步骤4:在当前目录下建立一个名为test的新目录,然后将工作目录切换到test下,尝试将/etc目录下的文件passwd拷贝到该目录下(cp 源文件目的目录)。
察看当前目录下的passwd文件的属主和文件权限.步骤5:尝试向当前目录下的passwd文件和/etc/passwd文件分别写入一些新内容(可使用echo “字符串” 〉>文件的命令),看看操作能否成功,如果不能成功,请说明原因。
操作系统实验 进程通信
进程通信(实验二)【实验目的】:掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法。
【实验原理】:邮箱机制类似于日常使用的信箱。
对于用户而言使用起来比较方便,用户只需使用send()向对方邮箱发邮件receive()从自己邮箱取邮件,send()和receive()的内部操作用户无需关心。
因为邮箱在内存中实现,其空间有大小限制。
其实send()和receive()的内部实现主要还是要解决生产者与消费者问题。
【实验内容】:进程通信的邮箱方式由操作系统提供形如send()和receive()的系统调用来支持,本实验要求学生首先查找资料了解所选用操作系统平台上用于进程通信的系统调用具体形式,然后使用该系统调用编写程序进行进程间的通信,要求程序运行结果可以直观地体现在界面上。
在此基础上查找所选用操作系统平台上支持信号量机制的系统调用具体形式,运用生产者与消费者模型设计实现一个简单的信箱,该信箱需要有创建、发信、收信、撤销等函数,至少能够支持两个进程互相交换信息,比较自己实现的信箱与操作系统本身提供的信箱,分析两者之间存在的异同。
实验背景介绍进程间通信有如下目的:数据的传输,共享数据,通知事情,资源共享,进程控制。
进程间的通信机制(IPC),就是多进程相互通信,交换信息的方法。
Linux IPC机制包括,信号和管道是其中的两个,还支持传统的UNIX SYSTM-V 的IPC 机制。
信号主要用来通知进程异步事情的发生,最初信号设计的目的是为了处理错误,他们也用来作为最基本的IPC机制。
管道是单向的,先进先出,先入先出,无结构的,固定大小的数据流。
UNIX System V 机制中的三种进程间通信机制,它们是:消息队列:用于进程之间传递分类的格式化数据信号量:用于通信之间的同步控制。
信号量通常与共享存储器方式一起使用。
共享内存:使不同进程通过共享彼此的虚拟空间而达到相互对共享区操作和数据通信。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验六:Linux进程间通信(2)(4课时)实验目的:理解进程通信原理;掌握进程中信号量、共享内存、消息队列相关的函数的使用。
实验原理: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_RMIDIPC_STAT : 该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。
IPC_SET : 该命令用来设置消息队列的属性,要设置的属性存储在buf 中。
IPC_RMID : 从内核中删除 msqid 标识的消息队列。
实验内容:1、完成教材上信号量实例,想一下ftok函数的作用?修改例子,创建2个进程完成原来父子进程对应的操作。
子进程代码:#include<sys/types.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/sem.h>#include<sys/ipc.h>#define DELAY_TIME 3union semun{int val;struct semid_ds *buf;unsigned short *array;};int init_sem(int sem_id,int init_value){union semun sem_union;sem_union.val = init_value;if(semctl(sem_id,0, SETVAL,sem_union)==-1){perror("Initialize semaphore");return -1;}return 0;}int del_sem(int sem_id){union semun sem_union;if(semctl(sem_id,0,IPC_RMID,sem_union)==-1) {perror("Delete semaphore");return -1;}}int sem_p(int sem_id){struct sembuf sem_b;sem_b.sem_num =0 ;sem_b.sem_op =-1;sem_b.sem_flg=SEM_UNDO;if(semop(sem_id,&sem_b,1)==-1){perror("P operation");return -1;}return 0;}int sem_v(int sem_id){struct sembuf sem_b;sem_b.sem_num =0 ;sem_b.sem_op =1;sem_b.sem_flg=SEM_UNDO;if(semop(sem_id,&sem_b,1)==-1){perror("V operation");return -1;}return 0;}int main(){pid_t result;int sem_id;sem_id =semget(ftok(".",'a'),1,0666|IPC_CREAT);init_sem(sem_id,0);printf("Child process will wait for some seconds...\n");sleep(DELAY_TIME);printf("The returned valud is %d in the child process(PID = %d)\n",result,getpid());sem_v(sem_id);}等待进程:#include<sys/types.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/sem.h>#include<sys/ipc.h>#define DELAY_TIME 3union semun{int val;struct semid_ds *buf;unsigned short *array;};int init_sem(int sem_id,int init_value){union semun sem_union;sem_union.val = init_value;if(semctl(sem_id,0, SETVAL,sem_union)==-1){perror("Initialize semaphore");return -1;}return 0;}int del_sem(int sem_id){union semun sem_union;if(semctl(sem_id,0,IPC_RMID,sem_union)==-1){perror("Delete semaphore");return -1;}}int sem_p(int sem_id){struct sembuf sem_b;sem_b.sem_num =0 ;sem_b.sem_op =-1;sem_b.sem_flg=SEM_UNDO;if(semop(sem_id,&sem_b,1)==-1){perror("P operation");return -1;}return 0;}int sem_v(int sem_id){struct sembuf sem_b;sem_b.sem_num =0 ;sem_b.sem_op =1;sem_b.sem_flg=SEM_UNDO;if(semop(sem_id,&sem_b,1)==-1){perror("V operation");return -1;}return 0;}int main(){pid_t result;int sem_id;sem_id =semget(ftok(".",'a'),1,0666|IPC_CREAT);init_sem(sem_id,0);sem_p(sem_id);printf("The returned value is %d in the father process (PID =%d)\n",result,getpid());sem_v(sem_id);del_sem(sem_id);}2、完成教材上共享内存实例,查看运行情况。