实验1-进程控制
编写程序,演示多进程并发执行和进程软中断、管道通信。
(1) 父进程使用系统调用pipe( )建立一个管道,然后使用系统调用fork()创建两个子进程,子进程1和子进程2;
(2) 子进程1每隔1秒通过管道向子进程2发送数据: I send you x times. (x初值为1,每次发送后做加一操作)
(3) 子进程2从管道读出信息,并显示在屏幕上;
(4) 父进程用系统调用signal()捕捉来自键盘的中断信号(即按Ctrl+C键);当捕捉到中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:
Child Process l is Killed by Parent!
Child Process 2 is Killed by Parent!
(5) 父进程等待两个子进程终止后,释放管道并输出如下的信息后终止
Parent Process is Killed!
(1)思路:
按照实验内容,我们需要用父进程创建两个子进程,从而实现子进程之间通过管道(除此之外,还有mmap,fifo通信方式)来实现进程间通信。所以我们需要首先创建出两个子进程(这里注意fork函数使用的时候,避免子进程再创建出新的子子进程的问题,这样可能会导致整个程序退出的时候出现孤儿进程)。具体的进程通信步骤会在下面说明,还有就是Linux下信号的使用,父进程接受到来自键盘的中断信号(我们可以在终端输入kill -l来查看不同的类型)的时候,父进程捕获信号,然后想子进程发出kill信号。
(2)实现代码:
int fd[2];//fd[0] 读端 fd[1] 写端 int ret = pipe(fd);
这里是首先创建两个文件描述符,一个是读端(创建出的子进程中的一个来操作读端),一个是写端(另一个子进程操作写端);然后创建一个管道,参数就是我们刚刚创建的文件描述符。
for(; i<number; ++i) {//循环创建两个字线程 pid_t pid = fork(); if(pid == 0) { break; }//防止出现子进程再创建出进程 }
这里我是循环创建了两个子进程,并且在循环体内部需要判断我的是否是子进程想要再创建子进程(这里可以尝试不加if判断,然后在终端下用ps命令查看是不是只创建了3个进程)
signal(SIGINT,func0);
这里我们在父进程中添加捕获ctrl+c信号的signal函数,捕获到之后执行func0函数,想子进程发送kill信号
下面是父子进程具体需要执行的内容:
父进程:
close(fd[0]);//父进程需要关闭pipe的读端和写端 close(fd[1]); pid_t wpid; //阻塞等待子进程执行完毕回收子进程资源 while( (wpid = waitpid(-1, NULL, WNOHANG)) != -1) { if(wpid == 0) { continue; } }
写端子进程:
int x = 1; signal(SIGINT,SIG_IGN); signal(2,func1); while (1) { //子进程1每经过1s向子进程2发送数据 sleep(1); //向子进程2写入数据 关闭读端 close(fd[0]); char p[64]; sprintf(p,"I send you %d times.\n",x); write(fd[1], p, sizeof(p)); x++; } close(fd[1]);
读端子进程:
close(fd[1]);//从管道读出数据 关闭写端 signal(SIGINT,SIG_IGN); signal(2,func2); while(1) { char buf[1024]; read(fd[0], buf, sizeof(buf)); printf("%s", buf); } close(fd[0]);
(4)实验结果