问题描述
假设我有以下名为 program.c 的程序
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
int function(char **argv) {
pid_t pid = fork();
if (pid > 0) {
execv(*argv,argv);
}
int value=0;
return value;
}
int main(int argc,char **argv) {
int return2;
return2 = function(argv+1);
printf("%d\n",return2);
}
而我执行./program /bin/ls
,为什么ls在return2的printf
之后执行?
示例:./program /bin/ls
返回
0
file1
file2
file3
这与换行符(缓冲区相关)无关,因为即使我从 printf 中删除了 \n,行为也是一样的。
我希望 execv 在子进程有时间到达 ls
之前立即打印 printf
。
解决方法
你的父进程不会等待子进程退出,它会在调用function
后立即从main
返回到fork
,然后main
也会立即完成它所做的。
甚至可能在子进程开始运行之前父进程就完成了。
使用wait
(或相关函数)等待子进程退出,并能够获取其退出码。
以下建议代码:
- 干净地编译
- 检查错误并报告
- 执行所需的功能
- 父进程等待子进程完成
现在,建议的代码:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int function(char **argv)
{
pid_t pid = fork();
if (pid == 0)
{ // then child process
execv(*argv,argv);
perror( "execv failed" );
exit( EXIT_FAILURE );
}
if( pid < 0 )
{
perror( "fork failed" );
exit( EXIT_FAILURE );
}
//if( pid > 0 )
// then parent process
int status;
waitpid( pid,&status,0 );
return status;
}
int main(int argc,char **argv)
{
int return2;
if( argc < 2 )
{
fprintf( stderr,"USAGE: %s cmdToRun\n",argv[0] );
exit( EXIT_FAILURE );
}
return2 = function(argv+1);
printf("%d\n",return2);
}