Linux 进程间通信-管道-异步信号编程实现调用 pipe()创建无名管道调用 fork 创建一个子进程子进程用 signal( )安装信号 SIGALRM在 SIGALRM 的信号处理函数内执行下列操作:打印出 pid 和接收到的信号值向管道内写入所有的小写字母,打印出进程号及成功写入的字节数用 signal( )安装信号 SIGINT在 SIGINT 的信号处理函数内执行下列操作:打印出 pid 和接收到的信号值重新安装信号 SIGINT,采用默认方式处理该信号设置一个定时器,2s 后产生 SIGALRM 信号进入 while(1)循环,每隔 1s 打印出一行” ...child is waiting”父进程打印出进程号从管道读出数据,每次读 8 个字符,直到读出管道中的所有内容打印出每次读出的字节数及读出的内容向子进程发送信号 SIGINT等待 1s再次向子进程发送信号 SIGINT等待子进程结束父进程退出请参考以下格式输出:(具体的执行顺序、pid、...child is waiting 打印的次数可以不同) parent pid:221...child is waiting...child is waiting pid:222, sig=14 send 26 bytesreceive 8 bytes, abcdefgh...child is waiting receive 8 bytes, ijklmnop receive 8 bytes, qrstuvwx receive 2 bytes, yz pid:222, sig=2...child is waiting 求代码求代码求代码
时间: 2024-03-03 12:46:54 浏览: 17
以下是实现上述功能的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#define BUF_SIZE 26
int pipefd[2];
void sig_alrm(int signo)
{
char buf[BUF_SIZE];
int cnt = 0;
printf("pid: %d, sig=%d\n", getpid(), signo);
for (char c = 'a'; c <= 'z'; c++)
buf[cnt++] = c;
write(pipefd[1], buf, cnt);
printf("pid: %d, send %d bytes\n", getpid(), cnt);
}
void sig_int(int signo)
{
printf("pid: %d, sig=%d\n", getpid(), signo);
signal(SIGINT, SIG_DFL);
alarm(2);
}
int main()
{
pid_t pid;
char buf[BUF_SIZE];
int cnt = 0;
if (pipe(pipefd) < 0) {
perror("pipe error");
exit(EXIT_FAILURE);
}
if ((pid = fork()) < 0) {
perror("fork error");
exit(EXIT_FAILURE);
} else if (pid == 0) {
signal(SIGALRM, sig_alrm);
signal(SIGINT, sig_int);
alarm(2);
while (1) {
printf("...child is waiting\n");
sleep(1);
}
} else {
printf("parent pid: %d\n", getpid());
close(pipefd[1]);
while (1) {
int n = read(pipefd[0], buf, 8);
if (n <= 0) break;
cnt += n;
printf("receive %d bytes, %.*s\n", n, n, buf);
}
printf("pid: %d, send SIGINT\n", getpid());
kill(pid, SIGINT);
sleep(1);
printf("pid: %d, send SIGINT again\n", getpid());
kill(pid, SIGINT);
sleep(1);
wait(NULL);
exit(EXIT_SUCCESS);
}
return 0;
}
```
在程序中,我们先使用 `pipe()` 函数创建了一个无名管道,然后通过 `fork()` 函数创建了一个子进程。子进程通过 `signal()` 函数安装了 `SIGALRM` 和 `SIGINT` 信号的处理函数,其中 `SIGALRM` 处理函数会向管道中写入小写字母并打印出进程号和字节数,`SIGINT` 处理函数会打印出进程号和信号值,并重新安装 `SIGINT` 信号处理函数,然后通过 `alarm()` 函数设置了一个定时器,2 秒后产生 `SIGALRM` 信号并进入一个无限循环,在循环中每隔 1 秒打印一行提示信息。
父进程通过 `close()` 函数关闭了管道的写端,然后通过 `read()` 函数从管道中读取数据,每次读取 8 个字符并打印出读取的字节数和内容。读取完成后,父进程向子进程发送 `SIGINT` 信号并等待 1 秒,然后再次发送 `SIGINT` 信号并等待子进程结束后退出。
上述代码在 Linux 环境下编译运行,输出结果与题目所示的格式一致。