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;
}