实验六 Linux进程编程,Linux系统编程实验六:进程间通信

《Linux系统编程实验六:进程间通信》由会员分享,可在线阅读,更多相关《Linux系统编程实验六:进程间通信(10页珍藏版)》请在人人文库网上搜索。

1、实验六:进程间通信l 实验目的:学会进程间通信方式:无名管道,有名管道,信号,消息队列,l 实验要求:(一)在父进程中创建一无名管道,并创建子进程来读该管道,父进程来写该管道(二)在进程中为SIGBUS注册处理函数,并向该进程发送SIGBUS信号(三)创建一消息队列,实现向队列中存放数据和读取数据l 实验器材:软件:安装了Linux的vmware虚拟机硬件:PC机一台l 实验步骤:(一)无名管道的使用1、编写实验代码pipe_rw.c#include #include #include #include #include #include int main()int pipe_fd2;/管道返。

2、回读写文件描述符pid_t pid;char buf_r100;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) /父进程执行代码/1、父进程先关闭了管道的读端close(pipe_fd0);/2、向管道写入字符串数据p_wbuf=&str1;write(pipe_fd1,p_wbuf,sizof(p_wbuf);p_。

3、wbuf=&str2;write(pipe_fd1,p_wbuf,sizof(p_wbuf);/3、关闭写端,并等待子进程结束后退出close(pipe_fd1);return 0;/*#include #include #include #include #include #include int main()int pipe_fd2;/管道返回读写文件描述符pid_t pid;char buf_r100;char* p_wbuf;int r_num;memset(buf_r,0,sizeof(buf_r);/将buf_r初始化char str1=holle;char str2=pipe;r。

4、_num=10;/*创建管道*/if(pipe(pipe_fd)0) /父进程执行代码close(pipe_fd0);/1、父进程先关闭了管道的读端p_wbuf=str1;/2、向管道写入字符串数据write(pipe_fd1,p_wbuf,sizeof(str1);sleep(1);p_wbuf=str2;write(pipe_fd1,p_wbuf,sizeof(str2);close(pipe_fd1);/3、关闭写端,并等待子进程结束后退出exit(1);/printf(father error!);return 0;*/2、编译应用程序pipe_rw.c3、运行应用程序子进程先睡两秒让。

5、父进程先运行,父进程分两次写入“hello”和“pipe”,然后阻塞等待子进程退出,子进程醒来后读出管道里的内容并打印到屏幕上再退出,父进程捕获到子进程退出后也退出4、由于fork函数让子进程完整地拷贝了父进程的整个地址空间,所以父子进程都有管道的读端和写端。我们往往希望父子进程中的一个进程写一个进程读,那么写的进程最后关掉读端,读的进程最好关闭掉写端(二)信号处理1、编写实验代码sig_bus.c#include #include #include /1、自定义信号处理函数,处理SIGBUS信号,打印捕捉到信号即可static void signal_handler(int signo)if。

6、(signo =SIGBUS)printf(“n I have get SIGBUS”);exit(EXIT_FAILURE);int main()printf(Waiting for signal SIGBUS n );/2、注册信号处理函数if(signal(SIGBUS,signal_handler)=SIG_ERR)fprintf(stderr,”cannot handle SIGBUSn”);exit(EXIT_FAILURE);pause();/将进程挂起直到捕捉到信号为止exit(0);return 0;/*#include #include #include #include 。

7、/1、自定义信号处理函数,处理SIGBUS信号,打印捕捉到信号即可static void signal_handler(int signo)if(signo =SIGBUS)printf(I have get SIGBUS);exit(EXIT_FAILURE);int main()printf(Waiting for signal SIGBUS n );/2、注册信号处理函数if(signal(SIGBUS,signal_handler)=SIG_ERR)fprintf(stderr,cannot handle SIGBUSn);exit(EXIT_FAILURE);pause();/将进程。

8、挂起直到捕捉到信号为止exit(0);return 0;*/用signal系统调用为SIGBUS信号注册信号处理函数my_func,然后将进程挂起等待SIGBUS信号。所以需要向该进程发送SIGBUS信号才会执行自定义的信号处理函数2、编译应用程序sig_bus.c3、运行应用程序先先一个终端中运行sig_bus,会看到进程挂起,等待信号然后在另一个终端中,查找到运行sig_bus这个产生的进程号,用kill命令发送SIGBUS信号给这个进程我们可以看到前面挂起的进程在接收到这个信号后的处理用自定义信号处理函数my_func来处理,所以打印了I have get SIGBUS这样一句话l 上机。

9、报告要求:1、 总结pipe(),signal()的函数定义原型,返回值和参数的意义表头文件: #include定义函数: int pipe(int filedes2);函数说明(参数): pipe()会建立管道,并将文件描述词由参数filedes数组返回。filedes0为管道里的读取端,filedes1则为管道的写入端。返回值:若成功则返回零,否则返回-1,错误原因存于errno中。阻塞问题:当管道中的数据被读取后,管道为空。一个随后的read()调用将默认的被阻塞,等待某些数据写入。功能:管道是一种把两个进程之间的标准输入和标准输出连接起来的机制,从而提供一种让多个进程间通信的方法,当进。

10、程创建管道时,每次都需要提供两个文件描述符来操作管道。其中一个对管道进行写操作,另一个对管道进行读操作。对管道的读写与一般的IO系统函数一致,使用write()函数写入数据,使用read()读出数据。表头文件:#include功 能:设置某一信号的对应动作函数原型:void (*signal(int signum,void(* handler)(int)(int); 或者:typedef void(*sig_t) ( int ); sig_t signal(int signum,sig_t handler);可看成是signal()函数(它自己是带有两个参数,一个为整型,一个为函数指针的函数)。

11、,而这个signal()函数的返回值也为一个函数指针,这个函数指针指向一个带整型参数,并且返回值为void的一个函数。参数说明:第一个参数signum指明了所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号。 第二个参数handler描述了与信号关联的动作,它可以取以下三种值: (1)一个返回值为正数的函数地址此函数必须在signal()被调用前申明,handler中为这个函数的名字。当接收到一个类型为sig的信号时,就执行handler 所指定的函数。这个函数应有如下形式的定义: intfunc(int sig); sig是传递给它的唯一参数。执行了signal(。

12、)调用后,进程只要接收到类型为sig的信号,不管其正在执行程序的哪一部分,就立即执行func()函数。当func()函数执行结束后,控制权返回进程被中断的那一点继续执行。(2)SIGIGN 这个符号表示忽略该信号,执行了相应的signal()调用后,进程会忽略类型为sig的信号。 (3)SIGDFL 这个符号表示恢复系统对信号的默认处理。 函数说明:signal()会依参数signum 指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。当一个信号的信号处理函数执行时,如果进程又接收到了该信号,该信号会自动被储存而不会中断信号处理函数的执行,直到。

13、信号处理函数执行完毕再重新调用相应的处理函数。但是如果在信号处理函数执行时进程收到了其它类型的信号,该函数的执行就会被中断。返回值:返回先前的信号处理函数指针,如果有错误则返回SIG_ERR(-1)。 附加说明:在信号发生跳转到自定的handler处理函数执行后,系统会自动将此处理函数换回原来系统预设的处理方式,如果要改变此操作请改用sigaction()。下面的情况可以产生Signal: 1. 按下CTRL+C产生SIGINT 2. 硬件中断,如除0,非法内存访问(SIGSEV)等等 3. Kill函数可以对进程发送Signal 4. Kill命令。实际上是对Kill函数的一个包装 5.软件。

14、中断。如当Alarm Clock超时(SIGURG),当Reader中止之后又向管道写数据(SIGPIPE),等等命名管道FIFO功能:管道最大的劣势就是没有名字,只能用于有一个共同祖先进程的各个进程之间。FIFO代表先进先出,单它是一个单向数据流,也就是半双工,和管道不同的是:每个FIFO都有一个路径与之关联,从而允许无亲缘关系的进程访问。 头文件:#include #include 函数定义原型:int mkfifo(const char *pathname, mode_t mode);参数:这里pathname是路径名,mode是sys/stat.h里面定义的创建文件的权限.2、 利用有。

15、名管道FIFO实现类似第一个实验的功能,一个程序fifo_read.c写数据”Hi Linux”,另一个程序fifo_write.c读数据并打印出来。/fifo.read.c#include #include #include #include #include #include #include #include /#define FIFO fifoint main()int fdr,fd;char buf_r=Hi Linuxn;fd=mkfifo(fifo.txt,O_CREAT|O_RDWR|0666);if(fd#include #include #include #include #include #include #include /#define FIFO fifoint main()int fdw,fd;char buf100;memset(buf,0,sizeof(buf);fdw=open(fifo.txt,O_RDONLY);if(fdw0)printf(open error(W)!);exit(-1);/sleep(2);if(read(fdw,buf,100)0)printf(read error(W);exit(-1);printf(n%s,buf);close(fdw);return 0。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值