多进程学习3
本文主要描述如何启动一个独立的program并实现进程间的通信。
主进程main1:
void main( void ) { const char cmd_start[] = "start"; const char cmd_stop[] = "stop"; char str_read_fd[10]; char str_write_fd[10]; int file_pipes[2]; if (pipe(file_pipes) != 0) { printf( "pipe file_pipes error. " ); } pid_t child = fork(); if ( child == -1 ) { printf( "fork err. " ); exit(EXIT_FAILURE); } else if ( child == 0 ) // this is the child process { printf( "in child process. " ); printf(" child pid = %d ",getpid()); printf(" child ppid = %d ",getppid()); snprintf(str_read_fd, 10, "%d", file_pipes[0]); snprintf(str_write_fd, 10, "%d", file_pipes[1]); errno = execl( "/home/xa00087/temp/test/main/main2", "main2", str_read_fd, str_write_fd, "test3",( char * )NULL ); //errno = system("/home/xa00087/temp/test/main/main2"); //printf( "execl failed, error code: %d(%s)", errno, strerror( errno ) ); printf("main1 child process exit, errno=%d ", errno); //it don"t excute here if routine runs successfully. exit(EXIT_SUCCESS); } else { printf( "in parent process. " ); printf(" parent pid = %d ", getpid()); printf(" parent ppid = %d ", getppid()); close(file_pipes[0]); sleep(5); write(file_pipes[1], cmd_start, strlen(cmd_start)); int status; waitpid( child, &status, 0 ); printf("WIFEXITED( status ) = %d ", WIFEXITED( status )); printf("WEXITSTATUS( status ) = %d ", WEXITSTATUS( status )); printf("parent process %d exit ", getpid()); } exit(EXIT_SUCCESS); }
子进程main2:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <stdbool.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> int main(int argc,char *argv[]) { int i = 0; int pipe_read_fd; int pipe_write_fd; int read_count = 0; char buffer[50]; sleep(1); printf(" main2: pid = %d ", getpid()); printf("main2: ppid = %d ", getppid()); printf("argc = %d ", argc); for (i=0; i<argc; i++) { printf("argv[%d]=%s ", i, argv[i]); } sscanf(argv[1], "%d", &pipe_read_fd); sscanf(argv[2], "%d", &pipe_write_fd); pid_t child = fork(); if ( child == -1 ) // this is the child process { printf( "main2: fork err. " ); exit(EXIT_FAILURE); } else if ( child == 0 ) // this is the child process { int ret, maxFd; fd_set readset; FD_ZERO(&readset); FD_SET(pipe_read_fd, &readset); maxFd = pipe_read_fd; printf( "main2: in child process. " ); printf("main2: child pid = %d ", getpid()); printf("main2: child ppid = %d ", getppid());
ret = select(maxFd + 1, &readset, NULL, NULL, NULL); // monitor whether any fd has readable data
printf("main2: pipe_read_fd = %d ", pipe_read_fd);
if (pipe_read_fd >= 0 && FD_ISSET(pipe_read_fd, &readset)) { memset(buffer, 0, 50); read_count = read(pipe_read_fd, buffer, 50-1); printf("pipe read %d bytes: %s ", read_count, buffer); } i= 5; while (i-- >0) { sleep(1); printf("this is in main2 child progress! "); } printf("main2: child pid = %d ",getpid()); printf("main2: child ppid = %d ",getppid()); printf("main2 child progress exit! "); exit(EXIT_SUCCESS); } else { printf( "main2 process exit. " ); } exit(EXIT_SUCCESS); }
运行结果:
in parent process. parent pid = 18055 parent ppid = 45107 in child process. child pid = 18056 child ppid = 18055 main2: pid = 18056 main2: ppid = 18055 argc = 4 argv[0]=main2 argv[1]=3 argv[2]=4 argv[3]=test3 main2 process exit. main2: in child process. main2: child pid = 18057 main2: child ppid = 18056 WIFEXITED( status ) = 1 WEXITSTATUS( status ) = 0 parent process 18055 exit main2: pipe_read_fd = 3 pipe read 5 bytes: start xa00087@xalnx6:~/temp/test/main$ this is in main2 child progress! this is in main2 child progress! this is in main2 child progress! this is in main2 child progress! this is in main2 child progress! main2: child pid = 18057 main2: child ppid = 1 main2 child progress exit!
code分析:
main1中fork了一个子进程, 然后使用execl调用main2这个单独的program并替换调用原本子进程的程序,同时传递了pipe。
errno = execl( "/home/xa00087/temp/test/main/main2", "main2", str_read_fd, str_write_fd, "test3",( char * )NULL );
main2中 又创建了一个子进程来真正运行程序主体, main2主进程的返回结果会在main1中体现, 并且main1中也有waitpid等待main2的返回,
main2主进程结束之后, 其创建的子进程 PPID就会变为1, 而不再是main2的pid.
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: swoole深入学习 1. swoole初始
- 下一篇: 从源码说swoole进程间通信原理