实验五进程间通信.docx

上传人:b****8 文档编号:10369302 上传时间:2023-02-10 格式:DOCX 页数:27 大小:26.38KB
下载 相关 举报
实验五进程间通信.docx_第1页
第1页 / 共27页
实验五进程间通信.docx_第2页
第2页 / 共27页
实验五进程间通信.docx_第3页
第3页 / 共27页
实验五进程间通信.docx_第4页
第4页 / 共27页
实验五进程间通信.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

实验五进程间通信.docx

《实验五进程间通信.docx》由会员分享,可在线阅读,更多相关《实验五进程间通信.docx(27页珍藏版)》请在冰豆网上搜索。

实验五进程间通信.docx

实验五进程间通信

实验五进程间通信

UNIX/LINUX系统的进程间通信机构(IPC)允许在任意进程间大批量地交换数据。

本实验的目的是了解和熟悉LINUX支持的信号机制、管道机制、消息队列通信机制及共享存储区机制。

5.1信号机制实验

(一)

【实验目的】

1.了解什么是信号。

2.熟悉LINUX系统中进程之间软中断通信的基本原理。

【实验原理】

利用signal来实现发送信号和接受信号的原理

【实验内容】

1.编写一段程序,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到父进程发来的信号后,分别输出下列信息后终止:

Childprocess1iskilledbyparent!

Childprocess2iskilledbyparent!

父进程等待两个子进程终止后,输出以下信息后终止:

Parentprocessiskilled!

<参考程序>

#include

#include

#include

intwait_mark;

voidwaiting(),stop();

voidmain()

{intp1,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(“parentprocessiskilled!

\n”);

exit(0);

}

else/*在子进程2中*/

{

wait_mark=1;

signal(12,stop);

waiting();

lockf(1,1,0);

printf(“childprocess2iskilledbyparent!

\n”);

lockf(1,0,0);

exit(0);

}

}

else/*在子进程1中*/

{

wait_mark=1;

signal(10,stop);

waiting();

lockf(1,1,0);

printf(“childprocess1iskilledbyparent!

\n”);

lockf(1,0,0);

exit(0);

}

}

voidwaiting()

{

while(wait_mark!

=0);

}

voidstop()

{

wait_mark=0;

}

实验要求:

运行程序并分析结果。

如果把signal(SIGINT,stop)放在

号和

号位置,结果会怎样并分析原因。

该程序段前面部分用了两个wait(0),为什么?

该程序段中每个进程退出时都用了语句exit(0),为什么?

 

5.2信号机制实验

(二)

【实验目的】

学习signal的函数的使用

【实验原理】

利用signal的函数的机制来实习我们发送截获信号的功能

【实验内容】

修改上面的程序,增加语句signal(SIGINT,SIG_IGN)和语句signal(SIGQUIT,SIG_IGN),再观察程序执行时屏幕上出现的现象,并分析其原因。

<参考程序>

#include

#include

#include

intpid1,pid2;

intEndFlag=0;

pf1=0;

pf2=0;

voidIntDelete()

{

kill(pid1,10);

kill(pid2,12);

EndFlag=1;

}

voidInt1()

{

printf(“childprocess1iskilledbyparent!

\n”);

exit(0);

}

voidInt2()

{

printf(“childprocess2iskilledbyparent!

\n”);

exit(0);

}

main()

{

intexitcode;

signal(SIGINT,SIG_IGN);

signal(SIGQUIT,SIG_IGN);

while((pid1=fork())==-1);

if(pid1==0)

{

signal(SIGUSR1,Int1);

signal(SIGINT,SIG_IGN);

pause();

exit(0);

}

else

{

while((pid2=fork())==-1);

if(pid2==0)

{

signal(SIGUSR2,Int2);

signal(SIGINT,SIG_IGN);

pause();

exit(0);

}

else

{

signal(SIGINT,IntDelete);

waitpid(-1,&exitcode,0);/*等待任何子进程中断或结束*/

printf(“parentprocessiskilled\n”);

exit(0);

}

}

}

实验要求:

运行程序并分析结果。

司机售票员问题(选做题)

编程用fork()创建一个子进程代表售票员,司机在父进程中,再用系统调用signal()让父进程(司机)捕捉来自子进程(售票员)发出的中断信号,让子进程(售票员)捕捉来自(司机)发出的中断信号,以实现进程间的同步运行。

 

5.3管道通信实验

(一)

【实验目的】

1、了解什么是管道

2、熟悉UNIX/LINUX支持的管道通信方式

 【实验内容】

编写程序实现进程的管道通信。

用系统调用pipe()建立一管道,二个子进程P1和P2分别向管道各写一句话:

   Child1issendingamessage!

   Child2issendingamessage!

父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,后P2)。

参考程序

#include

#include

#include

intpid1,pid2;

 

main()

{

intfd[2];

charoutpipe[100],inpipe[100];

pipe(fd);                      /*创建一个管道*/

while((pid1=fork())==-1);

if(pid1==0)

 {

lockf(fd[1],1,0);

   sprintf(outpipe,"child1processissendingmessage!

");

/*把串放入数组outpipe中*/

   write(fd[1],outpipe,50);    /*向管道写长为50字节的串*/

   sleep(5);                /*自我阻塞5秒*/

   lockf(fd[1],0,0);

   exit(0);

           }

else

          {

while((pid2=fork())==-1);

   if(pid2==0)

{   lockf(fd[1],1,0);          /*互斥*/

  sprintf(outpipe,"child2processissendingmessage!

");

                write(fd[1],outpipe,50);

                sleep(5);

          lockf(fd[1],0,0);

                exit(0);

           }

              else

               { 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);

              }

       }

}

五、运行结果

  延迟5秒后显示

child1processissendingmessage!

      再延迟5秒

child2processissendingmessage!

5.4管道通信实验

(二)

【实验目的】

1、掌握有名管道的创建和读写方式

2、熟悉UNIX/LINUX支持的有名管道通信方式

 【实验内容】

1.创建有名管道

2.本进程执行循环等待数据被写入到管道中并读有名管道

3.打开有名管道并写数据到名管道

参考代码:

//read_fifo.c

#include

#include

#include

#include

#include

#include

#include

#defineBUFFER_SIZE1024

intmain(intargc,char**argv)

{

intfd;

if(argc<2)

{

fprintf(stdout,"Usage:

%s\n",argv[0]);

exit

(1);

}

//intopen(constchar*path,intoflag,...);

if((fd=open(argv[1],O_RDONLY))<0)

{

fprintf(stderr,"openfifo%sforreadingfailed:

%s\n",argv[1],strerror(errno));

exit

(1);

}

fprintf(stdout,"openfifo%sforreadingsuccessed.\n",argv[0]);

charbuffer[BUFFER_SIZE];

ssize_tn;

while

(1)

{

again:

//ssize_tread(intfd,void*buf,size_tcount);

if((n=read(fd,buffer,BUFFER_SIZE))<0)

{

if(errno==EINTR)

{

gotoagain;

}

else

{

fprintf(stderr,"readfailedon%s:

%s\n",argv[1],strerror(errno));

exit

(1);

}

}

elseif(n==0)

{

fprintf(stderr,"peerclosedfifo.\n");

break;

}

else

{

buffer[n]='\0';

fprintf(stdout,"read%dbytesfromfifo:

%s\n",n,buffer);

}

}

return0;

}

//write_fifo.c

#include

#include

#include

#include

#include

#include

#include

#include

#defineBUFFER_SIZE1024

voidsignal_handler(ints);

intmain(intargc,char**argv)

{

intfd;

if(argc<2)

{

fprintf(stdout,"Usage:

%s\n",argv[0]);

exit

(1);

}

signal(SIGPIPE,signal_handler);

//intopen(constchar*path,intoflag,...);

if((fd=open(argv[1],O_WRONLY))<0)

{

fprintf(stderr,"openfifo%sforwrittingfailed:

%s\n",argv[1],strerror(errno));

exit

(1);

}

fprintf(stdout,"openfifo%sforwrittingsuccessed.\n",argv[0]);

charbuffer[BUFFER_SIZE];

ssize_tn;

//char*fgets(char*s,intsize,FILE*stream);

while(fgets(buffer,BUFFER_SIZE,stdin))

{

again:

//ssize_twrite(intfd,constvoid*buf,size_tcount);

if((n=write(fd,buffer,strlen(buffer)))<0)

{

if(errno==EINTR)

{

gotoagain;

}

else

{

fprintf(stderr,"write()failedonfifo:

%s\n",strerror(errno));

//FIXME:

break;

}

}

}

return0;

}

voidsignal_handler(ints)

{

fprintf(stdout,"Caughtsignal%d\n",s);

}

//create_fifo.c

#include

#include

#include

#include

#include

intmain(intargc,char**argv)

{

if(argc<2)

{

fprintf(stdout,"Usage:

%s\n",argv[0]);

exit

(1);

}

//intmkfifo(constchar*path,mode_tmode);

if(mkfifo(argv[1],0644)<0)

{

fprintf(stderr,"mkfifo()failed:

%s\n",strerror(errno));

exit

(1);

}

return0;

}

5.5共享内存通信实验

【实验目的】

1、掌握共享内存的创建和读写方式

2、熟悉UNIX/LINUX支持的共享内存通信方式

 【实验内容】

1.创建共享内存

2.写入到共享内存

3.读数据从共享内存

代码参考:

//write.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#defineMAPPED_FILENAME"/tmp/test.mmap.1"

intmain(intargc,char**argv)

{

intfd;

if(argc<2)

{

fprintf(stdout,"Usage:

%s\n",argv[0]);

exit

(1);

}

//XXX:

step1,openfile,getafd

//intopen(constchar*pathname,intflags,mode_tmode);

if((fd=open(argv[1],O_RDWR|O_CREAT|O_EXCL,0644))<0)

{

if(errno==EEXIST)

{

fprintf(stderr,"Fatalerror:

Thetargetmappedfileexisted,exit.\n");

}

else

{

fprintf(stderr,"Error:

openfilefailed:

(errno=%d)%s\n",errno,strerror(errno));

}

exit

(1);

}

off_toffset;

offset=1024;

//XXX:

step2,createaholefile

//off_tlseek(intfildes,off_toffset,intwhence);

if(lseek(fd,offset,SEEK_SET)==(off_t)-1)

{

fprintf(stderr,"lseek()failed:

%s\n",strerror(errno));

//FIXME:

unlinkthefile

close(fd);

exit

(1);

}

ssize_tn;

//ssize_twrite(intfd,constvoid*buf,size_tcount);

if((n=write(fd,"",1))<0)

{

fprintf(stderr,"write()failed:

%s\n",strerror(errno));

exit

(1);

}

/*

*Onsuccess,mmapreturnsapointertothemappedarea.Onerror,thevalueMAP_FAILED(thatis,(void*)-1)isreturned,anderrnoissetappropriately.Onsuccess,munmapreturns0,onfailure-1,anderrnoisset(probablytoEINVAL).

*/

/*

PROT_EXECPagesmaybeexecuted.

PROT_READPagesmayberead.

PROT_WRITEPagesmaybewritten.

PROT_NONEPagesmaynotbeaccessed.

*/

void*p;

//XXX:

step3,mmap(),getapointer

//void*mmap(void*start,size_tlength,intprot,intflags,intfd,off_toffset);

if((p=mmap(NULL,1024,PROT_WRITE,MAP_SHARED,fd,0))==MAP_FAILED)

{

fprintf(stderr,"mmap()failed:

%s\n",strerror(errno));

close(fd);

exit

(1);

}

close(fd);

fprintf(stdout,"mappedfiletomemory,size=%d\n",1024);

//XXX:

step4,read/writeonsharedmemory

char*banner="helloworld.";

//void*memcpy(void*dest,constvoid*src,size_tn);

memcpy(p+256,banner,strlen(banner));

//XXX:

step5,munmap();

//intmunmap(void*start,size_tlength);

pause();

//close(fd);

return0;

}

//read.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#defineMAPPED_FILENAME"/tmp/test.mmap.1"

#defineBUFFER_SIZE1024

intmain(intargc,char**argv)

{

intfd;

if(argc<2)

{

fprintf(stdout,"Usage:

%s\n",argv[0]);

exit

(1);

}

//XXX:

step1,openfile,getafd

//intopen(constchar*pathname,intflags,mode_tmode);

if((fd=open(argv[1],O_RDWR))<0)

{

fprintf(stderr,"Error:

openfile

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 调查报告

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1