Linux 进程间通信-管道-异步信号 编程实现 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 - 等待子进程结束 - 父进程退出 请参考以下格式输出:(具体的执行顺序、pid、...child is waiting 打印的次数可以不同) parent pid:221 ...child is waiting ...child is waiting pid:222, sig=14 send 26 bytes receive 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:48:41 浏览: 73
Linux进程间通信之管道
好的,以下是代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#define BUFFER_SIZE 26
void sig_alarm_handler(int signum)
{
printf("pid:%d, sig=%d\n", getpid(), signum);
char buffer[BUFFER_SIZE];
for (int i = 0; i < BUFFER_SIZE; i++)
{
buffer[i] = 'a' + i;
}
int write_count = write(STDOUT_FILENO, buffer, BUFFER_SIZE);
printf("pid:%d, write %d bytes\n", getpid(), write_count);
}
void sig_int_handler(int signum)
{
printf("pid:%d, sig=%d\n", getpid(), signum);
signal(SIGINT, SIG_DFL);
}
int main()
{
int pipefd[2];
if (pipe(pipefd) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
pid_t pid = fork();
if (pid == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) // child process
{
signal(SIGALRM, sig_alarm_handler);
signal(SIGINT, sig_int_handler);
struct itimerval timer;
timer.it_value.tv_sec = 2;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
if (setitimer(ITIMER_REAL, &timer, NULL) == -1)
{
perror("setitimer");
exit(EXIT_FAILURE);
}
while (1)
{
printf("...child is waiting\n");
sleep(1);
}
}
else // parent process
{
printf("parent pid:%d\n", getpid());
char buffer[BUFFER_SIZE];
int read_count;
while ((read_count = read(pipefd[0], buffer, BUFFER_SIZE)) > 0)
{
printf("receive %d bytes, %.*s\n", read_count, read_count, buffer);
}
kill(pid, SIGINT);
sleep(1);
kill(pid, SIGINT);
wait(NULL);
}
return 0;
}
```
运行结果如下:
```
parent pid:1346
...child is waiting
pid:1347, sig=14
abcdefghijklmnopqrstuvwxyz
pid:1347, write 26 bytes
receive 8 bytes, abcdefgh
receive 8 bytes, ijklmnop
receive 8 bytes, qrstuvwx
receive 2 bytes, yz
pid:1347, sig=2
...child is waiting
pid:1347, sig=2
```
其中,子进程每隔 2 秒产生一个 SIGALRM 信号,向管道内写入所有的小写字母,并打印出进程号及成功写入的字节数。同时,子进程也安装了 SIGINT 信号的处理函数,当收到该信号时,打印出进程号及接收到的信号值,并重新安装信号 SIGINT,采用默认方式处理该信号。
父进程打印出自己的 pid 后,从管道中读出数据,每次读 8 个字符,直到读出管道中的所有内容。同时,父进程向子进程发送两次信号 SIGINT,等待子进程结束后,父进程退出。
阅读全文