pipe函数
以下是一个使用C语言编写的通过管道(pipe)进行进程间通信的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>int main() {int pipefd[2];pid_t pid;char buffer[50];// 创建管道if (pipe(pipefd) == -1) {perror("pipe");exit(EXIT_FAILURE);}// 创建子进程pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}// 子进程if (pid == 0) {close(pipefd[1]); // 关闭写端// 从管道读取数据read(pipefd[0], buffer, sizeof(buffer));printf("子进程读取到的数据:%s\n", buffer);// 关闭读端close(pipefd[0]);exit(EXIT_SUCCESS);}// 父进程else {close(pipefd[0]); // 关闭读端char message[] = "Hello from parent process!";// 将数据写入管道write(pipefd[1], message, sizeof(message));printf("父进程写入数据成功!\n");// 关闭写端close(pipefd[1]);exit(EXIT_SUCCESS);}
}
该示例中,首先使用pipe函数创建一个管道,然后调用fork函数创建一个子进程。在子进程中,通过read函数从管道中读取数据,并打印输出。在父进程中,通过write函数将数据写入管道。通过这种方式,子进程和父进程之间就可以进行通信了。请注意,在使用完管道后,需要分别关闭管道的读端和写端。
SIGCHLD,execvp、pipe
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>void sigchld_handler(int signum) {int status;pid_t pid;// 等待子进程退出并获取退出状态while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {if (WIFEXITED(status)) {printf("子进程 %d 正常退出,退出状态码: %d\n", pid, WEXITSTATUS(status));} else if (WIFSIGNALED(status)) {printf("子进程 %d 被信号终止,终止信号: %d\n", pid, WTERMSIG(status));}}
}int main() {int pipefds[2];pid_t pid;int status;struct sigaction sa;// 创建管道if (pipe(pipefds) == -1) {perror("pipe");exit(1);}// 注册SIGCHLD信号处理函数sa.sa_handler = sigchld_handler;sigemptyset(&sa.sa_mask);sa.sa_flags = SA_RESTART;if (sigaction(SIGCHLD, &sa, NULL) == -1) {perror("sigaction");exit(1);}// 创建子进程pid = fork();if (pid == -1) {perror("fork");exit(1);} else if (pid == 0) {// 子进程中将标准输出重定向到管道写端close(pipefds[0]); // 关闭管道读端dup2(pipefds[1], STDOUT_FILENO); // 将标准输出重定向到管道写端close(pipefds[1]); // 关闭管道写端// 执行外部命令char *args[] = {"ls", "-l", NULL};if (execvp(args[0], args) == -1) {perror("execvp");exit(1);}} else {// 父进程从管道读端读取子进程的输出close(pipefds[1]); // 关闭管道写端char buffer[1024];int nbytes;while ((nbytes = read(pipefds[0], buffer, sizeof(buffer))) > 0) {write(STDOUT_FILENO, buffer, nbytes);}// 等待子进程退出if (waitpid(pid, &status, 0) == -1) {perror("waitpid");exit(1);}// 检查子进程退出状态if (WIFEXITED(status)) {printf("子进程 %d 正常退出,退出状态码: %d\n", pid, WEXITSTATUS(status));} else if (WIFSIGNALED(status)) {printf("子进程 %d 被信号终止,终止信号: %d\n", pid, WTERMSIG(status));}}return 0;
}