本文主要描述如何启动一个独立的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.\n" );
}
pid_t child = fork();
if ( child == -1 )
{
printf( "fork err.\n" );
exit(EXIT_FAILURE);
}
else if ( child == 0 ) // this is the child process
{
printf( "in child process.\n" );
printf("\tchild pid = %d\n",getpid());
printf("\tchild ppid = %d\n",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\n", errno); //it don't excute here if routine runs successfully.
exit(EXIT_SUCCESS);
}
else {
printf( "in parent process.\n" );
printf("\tparent pid = %d\n", getpid());
printf("\tparent ppid = %d\n", 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\n", WIFEXITED( status ));
printf("WEXITSTATUS( status ) = %d\n", WEXITSTATUS( status ));
printf("parent process %d exit\n", 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("\nmain2: pid = %d\n", getpid());
printf("main2: ppid = %d\n", getppid());
printf("argc = %d \n", argc);
for (i=0; i<argc; i++) {
printf("argv[%d]=%s \n", 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.\n" );
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.\n" );
printf("main2: child pid = %d\n", getpid());
printf("main2: child ppid = %d\n", getppid());
ret = select(maxFd + 1, &readset, NULL, NULL, NULL); // monitor whether any fd has readable data
printf("main2: pipe_read_fd = %d\n", 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\n", read_count, buffer);
}
i= 5;
while (i-- >0) {
sleep(1);
printf("this is in main2 child progress! \n");
}
printf("main2: child pid = %d\n",getpid());
printf("main2: child ppid = %d\n",getppid());
printf("main2 child progress exit! \n");
exit(EXIT_SUCCESS);
}
else {
printf( "main2 process exit.\n" );
}
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.