使用系统调用pipe()建立一条管道先。两个子进程p1和分别向管道各写一句话:
Child1processissendingamessage!
Child2processissendingamessage!
而父进程则从管道中读出来自于两个子进程的信息并显示在屏幕上。
第一步
创建c文件夹,在它下面创建hello.c文件
mkdir cvim test.c
第二步
写入参考程序
程序
#include#include#includeint pid1,pid2; main() { int fd[3]; char outpipe[100],inpipe[100]; pipe(fd); while((pid1=fork())==-1); if(pid1==0) { printf("p1\n"); lockf(fd[1],1,0); sprintf(outpipe,"child1processissendingamessage!"); write(fd[1],outpipe,50); sleep(1); lockf(fd[1],0,0); exit(0); } else { while((pid2=fork())==-1); if(pid2==0) { printf("p2\n"); lockf(fd[1],1,0); sprintf(outpipe,"child2processissendingamessage!"); write(fd[1],outpipe,50); sleep(1); lockf(fd[1],0,0); exit(0); } else { printf("parent\n"); wait(0);/*同步*/ read(fd[0],inpipe,50);/*从管道中读长为50字节的串*/ printf("%s\n",inpipe); wait(0); read(fd[0],inpipe,50); printf("%s\n",inpipe); exit(0); } } }
结果
相关知识
无名管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
有名管道(namedpipe):有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
管道通信的特点:管道只能承载无格式字节流。
观察程序中的sleep(1)起什么作用?
答:延长子进程占用管道的时间,并没有让子进程1先输出而子进程2后输出的作用。
子进程1和2为什么也能对管道进行操作?
答:因为该pipe管道属于无名管道,调用pipe()的父进程及其子孙进程均能识别此文件描述符,能利用该文件(管道)进行通信。
(摘自实验报告书)
收起
展开全文
多线程操作系统

操作系统——实验三(进程间通信)——3.3.2

操作系统——实验三(进程间通信)——3.3.2 实验目的 1、了解linux系统中进程通信的基本原理。 2、分析进程竞争资源现象,学习解决进程互斥的方法。 3.3.2——软中断通信(选做) 编制一段程序,使用系统...
操作系统——实验三(进程间通信)——3.3.2

实验目的

1、了解linux系统中进程通信的基本原理。
2、分析进程竞争资源现象,学习解决进程互斥的方法。

3.3.2——软中断通信(选做)

编制一段程序,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:
childprocess1iskilledbyparent!
childprocess2iskilledbyparent!
父进程等待两个子进程终止后,输出以下信息后终止:
parentprocessiskilled!
第一步
创建c文件夹,在它下面创建hello.c文件
mkdir cvim test.c
第二步
写入参考程序
程序
#include#include#includevoidwaiting(),stop(); intwait_mark; main() { intp1,p2; if(p1=fork())/*创建子进程p1*/ { if(p2=fork())/*创建子进程p2*/ { wait_mark=1; signal(SIGINT,stop);/*接收到^c信号,转stop*/ waiting(); kill(p1,16);/*向p1发软中断信号16*/ kill(p2,17);/*向p2发软中断信号17*/ wait(0);/*同步*/ wait(0); printf("parentprocessiskilled!\n"); exit(0); } else { wait_mark=1; signal(SIGINT,stop); waiting(); lockf(1,0,0); printf("childprocess2iskilledbyparent!\n"); lockf(1,0,0); exit(0); } } else { wait_mark=1; signal(SIGINT,stop); waiting(); lockf(1,0,0); printf("childprocess1iskilledbyparent!\n"); lockf(1,0,0); exit(0); } } voidwaiting() { while(wait_mark!=0); } voidstop() { wait_mark=0; }
编译程序
gcc -o test test.c
记录结果
结果分析
因为fork()创建进程的速度慢于输出字符,所以先输出child后输出parent
如有错误请指证
收起
展开全文
操作系统多线程

操作系统——实验三(进程间通信)——3.3.3

2020-06-01 22:49:13
操作系统——实验三(进程间通信)——3.3.2 实验目的 1、了解linux系统中进程通信的基本原理。 2、分析进程竞争资源现象,学习解决进程互斥的方法。 3.3.3消息通信(必做) 使用系统调用msgget(),msgsnd(),...
操作系统——实验三(进程间通信)——3.3.3

实验目的

1、了解linux系统中进程通信的基本原理。
2、分析进程竞争资源现象,学习解决进程互斥的方法。

3.3.3消息通信

使用系统调用msgget(),msgsnd(),msgrcv()及msgctl()编制一长度为1K的消息发送和接收的程序。
〈程序设计〉
(1)为了便于操作和观察结果,用一个程序为“引子”,先后fork()两个子进程,SERVER和CLIENT,进行通信。
(2)SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER。SERVER每接收到一个消息后显示一句“(server)received”。
(3)CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后的一个消息,既是SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(client)sent”。
(4)父进程在SERVER和CLIENT均退出后结束。
第一步
创建c文件夹,在它下面创建test.c文件
mkdir cvim test.c
第二步
写入参考程序
程序
#include#include#include#include#define MSGKEY 75/*定义关键词MEGKEY*/ struct msgform/*消息结构*/ { long mtype; char mtxt[1030];/*文本长度*/ }msg; int msgqid,i; void CLIENT() { int i; msgqid=msgget(MSGKEY,0777); for(i=20;i>=1;i--) { msg.mtype=i; printf("(client)sent\n"); msgsnd(msgqid,&msg,1024,0);/*发送消息msg入msgid消息队列*/ } exit(0); "c/test3.c" 45L, 769C msgsnd(msgqid,&msg,1024,0);/*发送消息msg入msgid消息队列*/ } exit(0); } void SERVER() { msgqid=msgget(MSGKEY,0777|IPC_CREAT);/*由关键字获得消息队列*/ do { msgrcv(msgqid,&msg,1030,0,0);/*从队列msgid接受消息msg*/ printf("(server)receive\n"); }while(msg.mtype!=1);/*消息类型为1时,释放队列*/ msgctl(msgqid,IPC_RMID,0);//delete signal exit(0); } main() { if(fork()) SERVER(); else CLIENT(); wait(0); }
记录结果
分析
message的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造成上面现象,在多次sendmessage后才receivemessage.这一点有助于理解消息转送的实现机理。
消息通信的特点:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。消息的传递,自身就带有同步的控制.当等到消息的时候,进程进入睡眠状态,不再消耗CPU资源。(摘自实验指导书)
收起
展开全文
操作系统队列

操作系统——实验三(进程间通信)——3.3.1

2020-06-01 20:58:55
操作系统——实验三(进程间通信) 实验目的 1、了解linux系统中进程通信的基本原理。 2、分析进程竞争资源现象,学习解决进程互斥的方法。 3.3.1 通过Linux提供的系统调用signal()来说明如何执行一个预先...
操作系统——实验三(进程间通信)

实验目的

1、了解linux系统中进程通信的基本原理。
2、分析进程竞争资源现象,学习解决进程互斥的方法。

3.3.1

通过Linux提供的系统调用signal()来说明如何执行一个预先安排好的信号处理函数。

第一步
创建c文件夹,在它下面创建hello.c文件
mkdir cvim test.c
第二步
写入参考程序
程序
#include#include#include#includeint ctrl_c_count=0; void (*old_handler)(int); void ctrl_c(int); void main() { int c; /*设置ctrl+c产生的信号SIGINT的处理程序为ctrl_c.取代系统原来默认的处理程序*/ old_handler=signal(SIGINT,ctrl_c); /*不断输入字符,同时按多次ctrl+c,直到按回车结束*/ while((c=getchar())!='\n'); printf("ctrl_c_count=%d\n",ctrl_c_count); /*设置信号处理程序为原来的处理程序*/ (void)signal(SIGINT,old_handler); /*不断输入字符,ctrl+c结束*/ while((c=getchar())!='\n'); } /*对SIGINT信号的处理程序*/ void ctrl_c(int signum) { (void)signal(SIGINT,ctrl_c); ++ctrl_c_count; }
第三步
编译该文件,生成test
gcc -o test test.c
第四步
运行该文件记录结果
./test
结果分析:程序中的ctrl_c函数的功能是记录SIGINT(CTRL+c)的次数,所以ctrl_c_count=8,当使用默认的函数操作时,CTRL+c退出程序
相关知识
signal(sig,function):
允许调用进程控制软中断信号的处理。
头文件为:
#include
参数定义:
signal(sig,function);
int sig;
void(*func)();
其中:sig的值是:
SIGHVP挂起
SIGINT键盘按^c键或break键
SIGQUIT键盘按quit键
SIGILL非法指令
SIGIOTIOT指令
SIGEMTEMT指令
SIGFPE浮点运算溢出
SIGKILL要求终止进程
SIGBUS总线错
SIGSEGV段违例
SIGSYS系统调用参数错
SIGPIPE向无读者管道上写
SIGALRM闹钟
SIGTERM软件终结
SIGUSRI用户定义信号
SIGUSR2第二个用户定义信号
SIGCLD子进程死
SIGPWR电源故障
function的解释如下:
SIG_DEL:缺省操作。
对除SIGPWR和SIGCLD外所有信号的缺省操作是进程终结对信号SIGQUIT,SIGILL,SIGTRA,SIGIOT,SIGEMT,SIGFPE,SIGBUS,SIGSEGV和SIGSYS它产生一内存映像文件。
SIG_IGN:忽视该信号的出现。
Function:在该进程中的一个函数地址,在核心返回用户态时,它以软中断信号的序号作为参数调用该函数,对除了信号SIGILL,SIGTRAP和SIGTWR以外的信号,核心自动地重新设置软中断信号处理程序的值为SIG_DEL,一个进程不能捕获SIGKILL信号。
收起
展开全文
操作系统c++

操作系统原理实验三进程间通信

千次阅读2020-06-30 08:33:45
实验三进程间通信 1、实验目的Linux系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据。本实验的目的是使学生了解和熟悉Linux支持的消息通讯机制及管道通信机制。 2、实验预备内容 阅读Linux系统的msg.c、...
收起

操作系统实验--进程间通信

千次阅读2020-09-27 21:00:28
在Linux系统下用signal()函数进行进程间通信,pipe()函数创建管道进行数据传送。 四、源代码 1.软中断通信 #include#include#includevoid waiting(),stop(); int...
收起
操作系统

Linux进程间通信(三)---管道通信之有名管道及其基础实验

千次阅读2014-04-04 15:14:18
① 它可以使互不相关的两个进程间实现彼此通信; ② 该管道可以通过路径名来指出,并且在文件系统中是可见的。在建立了管道之后,两个进程就可以把它当做普通文件一样进行读写操作,使用非常方便; ③ FIFO...
收起

杭电操作系统实验三之利用Linux的共享内存通信机制实现两个进程间的通信

千次阅读2019-08-05 21:09:40
4)利用Linux的共享内存通信机制实现两个进程间的通信 编写程序sender,它创建一个共享内存,然后等待用户通过终端输入一串字符,并将这串字符通过共享内存发送给receiver;最后,它等待receiver的应答,收到应答...