编程实现 a) 调用 pipe()创建无名管道 b) 调用 fork 创建一个子进程 c) 子进程 - 用 signal( )安装信号 SIGALRM 在 SIGALRM 的信号处理函数内执行下列操作: 打印出 pid 和接收到的信号值 向管道内写入所有的小写字母,打印出进程号及成功写入的字节数 - 用 signal( )安装信号 SIGINT 在 SIGINT 的信号处理函数内执行下列操作: 打印出 pid 和接收到的信号值 重新安装信号 SIGINT,采用默认方式处理该信号 - 设置一个定时器,2s 后产生 SIGALRM 信号 - 进入 while(1)循环,每隔 1s 打印出一行” ...child is waiting” d) 父进程 - 打印出进程号 - 从管道读出数据,每次读 8 个字符,直到读出管道中的所有内容 打印出每次读出的字节数及读出的内容 - 向子进程发送信号 SIGINT - 等待 1s - 再次向子进程发送信号 SIGINT - 等待子进程结束 - 父进程退出
时间: 2024-03-03 21:48:27 浏览: 63
可以参考下面的代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
void sigint_handler(int sig) {
printf("PID %d received signal SIGINT(%d)\n", getpid(), sig);
signal(SIGINT, SIG_DFL); // 恢复默认信号处理方式
}
void sigalrm_handler(int sig) {
printf("PID %d received signal SIGALRM(%d)\n", getpid(), sig);
char buf[26] = "abcdefghijklmnopqrstuvwxyz\n";
int fd[2];
pipe(fd);
pid_t pid = fork();
if (pid < 0) {
perror("fork error");
exit(-1);
} else if (pid == 0) { // 子进程
close(fd[0]); // 关闭读端
printf("Child process %d is writing to pipe...\n", getpid());
int n = write(fd[1], buf, sizeof(buf));
printf("Child process %d wrote %d bytes to pipe\n", getpid(), n);
close(fd[1]);
exit(0);
} else { // 父进程
close(fd[1]); // 关闭写端
char buf[8];
int n;
printf("Parent process %d is reading from pipe...\n", getpid());
while ((n = read(fd[0], buf, sizeof(buf))) > 0) {
printf("Parent process %d read %d bytes: %.*s", getpid(), n, n, buf);
}
close(fd[0]);
kill(pid, SIGINT); // 发送 SIGINT 信号给子进程
sleep(1);
kill(pid, SIGINT); // 再次发送 SIGINT 信号给子进程
waitpid(pid, NULL, 0); // 等待子进程结束
printf("Parent process %d exited.\n", getpid());
exit(0);
}
}
int main() {
signal(SIGINT, sigint_handler);
signal(SIGALRM, sigalrm_handler);
printf("Parent process %d started.\n", getpid());
alarm(2); // 设置定时器,2s 后产生 SIGALRM 信号
while (1) {
printf("...child is waiting\n");
sleep(1); // 每隔 1s 打印一次
}
return 0;
}
```
注意事项:
1. 父进程和子进程都需要关闭管道的读写端,即使它们不需要用到。
2. 在子进程中,我们使用 `write()` 函数向管道中写入小写字母,然后关闭写端,这样父进程在读取数据时就能正确判断管道的结束位置。
3. 在父进程中,我们使用 `read()` 函数从管道中读取数据,每次读取 8 个字符,直到读到了管道的结束位置,也就是读取返回值为 0。
4. 在父进程中,我们使用 `kill()` 函数向子进程发送信号,等待子进程结束时使用 `waitpid()` 函数等待子进程结束。
阅读全文