Linux程序设计实验
- 格式:doc
- 大小:56.01 KB
- 文档页数:8
Linux程序设计实验7——进程通信1一、实验目的1.掌握常用的几种中断方法;2.掌握signal函数实现信号处理程序设计院;3.掌握多信号时的信号处理程序编写;4.掌握应用管道实现信号处理的方法。
二、实验任务与要求1.alarm函数产生的SIGALRM信号;2.应用signal函数实现信号处理程序编写;3.多信号时的信号处理程序编写;4.应用管道实现信号处理的编写;三、实验工具与准备计算机PC机,Linux Redhat Fedora Core6操作系统四、实验步骤与操作指导任务1:硬中断实例运行下列程序kk1.c:#include <unistd.h>int main(void){while(1);return 0;}(1)程序运行过程中,请你使用硬中断Ctrl+C或Ctrl-\中断程序的执行。
(2)可以使用信号SIGSEGV中断此程序,方法是先在后台运行此程序,得出程序进程号,然后用命令kill发送信号SIGSEGV,如下形式:[root@localhost root]# ./kk &[root@localhost root]# [1] 7940[root@localhost root]# kill -SIGSEGV 7940根据提示,运行程序,结果如下:任务2:使用软件中断。
alarm函数和SIGALRM信号,调用alarm函数设定一个闹钟,告诉内核在seconds秒之后给当前进程发SIGALRM信号,该信号的默认处理动作是终止当前进程。
这个函数的返回值是0或者是以前设定的闹钟时间还余下的秒数。
程序源代码kk2.c:#include <unistd.h>#include <stdio.h>int main(void){int counter;alarm(10);for(counter=0; 1; counter++)printf("counter=%d ", counter);return 0;}程序的作用是10秒钟之内不停地数数,10秒钟到了就被SIGALRM信号中断。
程序运行结果:任务3:程序设计。
设计一个程序,要求程序运行后进入无限循环,在无限循环中每3秒输出一条语句;当用户按下中断组合键(Ctrl+C)发送信号SIGINT,此时调用信号处理函数(自定义函数fun_ctrl_c)。
在程序正常结束前,再应用signal函数(用参数SIG_DFL),恢复系统对信号的默认处理方式。
提示:源代码可参考教材P211,例证-4(1)修改程序,要求程序运行后进入一个无限循环,当用户按下中断键(Ctrl+Z)时,进入程序的自定义信号处理函数,当用户再次按下中断键(Ctrl+Z)后,结束程序运行。
源程序代码:程序运行结果:(2)修改程序,要求程序运行后进入一个无限循环,当用户按下中断键(Ctrl+Z)时,进入程序的自定义信号处理函数,当用户再次按下中断键(Ctrl+Z)后,程序仍能继续运行。
源程序代码:程序运行结果:任务4 调试下列程序。
程序中能处理三种不同的信号,其中信号SIGINT(Ctrl+C键)和SIGTSTP(Ctrl+Z键)是可阻塞的,而信号SIGQUIT(Ctrl+\ 键)是不可阻塞的,程序源代码如下:#include<stdio.h>#include<stdlib.h>#include<signal.h>#include<sys/types.h>#include<unistd.h>void fun_ctrl_c();void fun_ctrl_z();void fun_ctrl_d();int main(){ /*C程序的主函数,开始入口 */int i;sigset_t set, pendset;struct sigaction action;(void) signal(SIGINT, fun_ctrl_c); /*调用fun_ctrl_c函数 */(void) signal(SIGTSTP,fun_ctrl_z);(void) signal(SIGQUIT, fun_ctrl_d);if (sigemptyset(&set) < 0) /*初始化信号集合 */perror("初始化信号集合错误");if (sigaddset(&set, SIGINT) < 0) /*把SIGINT信号加入信号集合 */perror("Ctrl+C加入信号集合错误");if (sigaddset(&set, SIGTSTP) < 0)perror("Ctrl+Z加入信号集合错误");if (sigprocmask(SIG_BLOCK, &set, NULL) < 0)perror("往信号阻塞集增加一个信号集合错误");else{for (i = 0; i < 10; i++) {printf("Ctrl+C、Ctrl+Z信号处理处于阻塞状态,能及时处理'Ctrl+\'信号\n "); sleep(3);}}if (sigprocmask(SIG_UNBLOCK, &set, NULL) < 0)/*当前的阻塞集中删除一个信号集合 */perror("从信号阻塞集删除一个信号集合错误");}void fun_ctrl_c() /*自定义信号处理函数 */{int n ;printf("\t你按了Ctrl+C 系统是不是很长时间没理你?\n");for(n=0;n<4;n++)printf("\t正在处理Ctrl+C信号处理函数 \n");}void fun_ctrl_z() /*自定义信号处理函数 */{int n ;printf("\t你按了Ctrl+Z 系统是不是很长时间没理你?\n");for(n=0;n<6;n++)printf("\t正在处理Ctrl+Z信号处理函数 \n");}void fun_ctrl_d( ) /*自定义信号处理函数 */{int n;printf("\t你按了'Ctrl+\' 系统及时地处理了此信号处理函数\n");for(n=0;n<2;n++)printf("\t正在处理Ctrl+/ 信号处理函数 \n");}问题:调试此程序,说明此程序的中断机制;说明此程序的中断机制:程序运行结果:任务5:程序设计。
设计一个程序要求创建一个管道,复制进程,父进程往管道中写入字符串,子进程从管道中读取前输出字符串。
提示:主程序调用pipe函数创建一个管道,调用fork函数创建进程;父进程中先用close(pipe_fd[0])关闭pipe_fd[0],剩下的pipe_fd[1]用来把数据写入管道,利用write函数写入字符串,然后用close(pipe_fd[1])关闭pipe_fd[1];子进程是用close(pipe_fd[1])关闭pipe_fd[1],剩下的pipe_fd[0]用来从管道读取数据,利用read函数读取字符串,然后用close(pipe_fd[0])关闭pipe_fd[0]。
#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/wait.h>#include<unistd.h>#include<string.h>int main ()pid_t result;int r_num;int pipe_fd[2];char buf_r[100],buf_w[100];memset(buf_r,0,sizeof(buf_r));if(pipe(pipe_fd)<0){printf("创建管道失败");return -1;}result=fork();if(result<0){perror("创建子进程失败");exit(0) ;}else if (result==0) /*子进程运行代码段*/{close(pipe_fd[1]);if((r_num=read(pipe_fd[0],buf_r,100))>0)printf("子进程从管道读取%d个字符,读取的字符串是:%s\n",r_num,buf_r); close(pipe_fd[0]);exit(0);}else /*父进程运行代码段*/{close(pipe_fd[0]);printf("请从键盘输入写入管道的字符串\n");scanf("%s",buf_w);if(write(pipe_fd[1],buf_w,strlen(buf_w))!=-1)printf("父进程向管道写入:%s\n",buf_w);close(pipe_fd[1]);waitpid(result,NULL,0);//调用waitpid, 阻塞父进程,等待子进程退出 exit(0);}问题:修改以上程序,要求父进程读取文件kk1.c内容(即任务1的源代码),把读出的字符串写入管道,子进程从管道中读取前输出字符串。
修改后的源程序代码:程序运行结果:。