1. linux 的fork()函数
(1)头文件
#include <sys/types.h>
#include <unistd.h>
(2)函数原型
pid_t fork(void);
返回值:成功调用返回两个值,子进程返回0.父进程返回子进程的pid,出错返回-1
(3)函数说明
一个现有的进程可以调用fork产生一个新的子进程。子进程拥有父进程的数据段,堆栈等资源的一个副本。
linux将父进程的地址空间复制给子进程,因此,子进程拥有和父进程一样的独立的地址空间。
由于复制时复制了父进程的堆栈段,所以两个进程都停留在fork函数中,等待返回。
子进程创建完毕,运行退出fork函数后会返回0,然后执行后续的代码;父进程也会退出fork函数,并返回子进程pid,然后运行后面的代码。
这就是为什么fork会返回两次的原因。
例如:
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
void test()
{
int pid;
pid = fork();
printf("start.. \n");
if(pid < 0)
{
printf("error \n");
}
else if(pid == 0)
{
printf("child process.\n");
}
else
{
printf("parent process.\n");
}
printf("end.. \n");
}
void end_work()
{
printf("end_work.. \n");
}
int main()
{
printf("first line.. \n");
test();
end_work();
return 0;
}
运行结果:
first line..
start..
child process.
end..
end_work..
start..
parent process.
end..
end_work..
2. system与exec的区别
system会新起一个子进程来调用要执行的命令。而exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。
system源码:
int system(const char * cmdstring){
pid_t pid;
int status;
if(cmdstring == NULL){
return (1);
}
if((pid = fork())<0){
status = -1;
}
else if(pid == 0){
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
exit(127); //子进程正常执行则不会执行此语句
}
else{
while(waitpid(pid, &status, 0) < 0){
if(errno != EINTER){
status = -1;
break;
}
}
}
return status;
}
waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。
如果执行成功则返回子进程识别码(PID) ,如果有错误发生则返回-1.
在/etc/profile中添加自己的bin路径
做一个简单的shell编程实例:删除当前文件夹下的.bak文件。