fork和vfork
vfork是老的实现方法又很多问题
vfork
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
printf("befor fork pid: %d\n",getpid());
int a = 10;
pid = vfork();
if(pid == -1)
{
perror("失败!\n");
return -1;
}
if(pid > 0){
printf("parent:pid: %d\n",getpid());
printf("parent:a:%d\n",a);
}
else if(pid == 0)
{
printf("child:%d,parent:%d\n",getpid(),getppid());
printf("child:a:%d\n",a);
}
return 0;
}
可以看到这里是有问题的
vfork常和 execve() 一起使用
就像Python中的os.system(cmd)这个函数,我们可以用这个函数来执行我们的shell脚本,单独的shell命令,或者是调用其他的程序,我们的execve()这个函数就和Python中的os.system函数类似,可以调用其他程序的执行,执行shell命令,,调用脚本等等功能。
int execve(const char *filename, char *const argv[],
char *const envp[]);
execve()执行程序由 filename决定。
filename必须是一个二进制的可执行文件,或者是一个脚本以#!格式开头的解释器参数参数。如果是后者,这个解释器必须是一个可执行的有效的路径名,但是不是脚本本身,它将调用解释器作为文件名。
argv是要调用的程序执行的参数序列,也就是我们要调用的程序需要传入的参数。
envp 同样也是参数序列,一般来说他是一种键值对的形式 key=value. 作为我们是新程序的环境。
注意,argv 和envp都必须以null指针结束。 这个参数向量和我们的环境变量都能够被我们的main函数调用,比如说我们可以定义为下面这个形式:
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
printf("befor fork pid: %d\n",getpid());
pid = vfork();
if(pid == -1)
{
perror("失败!\n");
return -1;
}
if(pid > 0){
printf("parent:pid: %d\n",getpid());
wait(NULL); //这里不等子进程会变孤儿进程
}
else if(pid == 0)
{
printf("child:%d,parent:%d\n",getpid(),getppid());
int r = 0;
r = execve("./hello", NULL,NULL);
if(r == -1)
{
perror("失败!\n");
}
exit(0);
}
return 0;
}
hello文件包含的东西
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
printf("你好!");
return 0;
}
我们调用系统的命令
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
printf("befor fork pid: %d\n",getpid());
pid = vfork();
if(pid == -1)
{
perror("失败!\n");
return -1;
}
if(pid > 0){
printf("parent:pid: %d\n",getpid());
wait(NULL); //这里不等子进程会变孤儿进程
}
else if(pid == 0)
{
printf("child:%d,parent:%d\n",getpid(),getppid());
int r = 0;
r = execve("/bin/ls", NULL,NULL);
if(r == -1)
{
perror("失败!\n");
}
exit(0);
}
return 0;
}
这里最好还是用fork函数
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
printf("befor fork pid: %d\n",getpid());
pid = fork();
if(pid == -1)
{
perror("失败!\n");
return -1;
}
if(pid > 0){
printf("parent:pid: %d\n",getpid());
wait(NULL); //这里不等子进程会变孤儿进程
}
else if(pid == 0)
{
printf("child:%d,parent:%d\n",getpid(),getppid());
int r = 0;
r = execve("/bin/ls", NULL,NULL);
if(r == -1)
{
perror("失败!\n");
}
exit(0);
}
return 0;
}