1、fork()一次调用两次返回?
#include <iostream>
#include <unistd.h>
using namespace std;
int main(){
pid_t pid ;
pid = fork();
if(pid == 0){
printf("I'm child,PID is %d\n",getpid());
}
else{
printf("I'm parent,PPid is %d,and Pid is %d\n",getpid(),pid);
}
}
运行结果:
I'm parent,PPid is 10037,and Pid is 10038
I'm child,PID is 10038
Press <RETURN> to close this window...
当新建进程的时候,子进程会拷贝父进程的堆栈段和数据段,这里是拷贝说明两个进程的上述资源已经完全分开了,这里唯一还在共享的就是代码段。新建进程的时候,任务管理其会在父进程堆栈段中存储其子进程的进程ID,而子进程没有子进程所以子进程相关位置存储的就是零。
当程序执行到fork()处的时候,程序分化为两个进程,但是两个进程还是共享代码段,任务调度器决定先执行哪一个Linux中首先执行父进程,在父进程中fork()返回子进程的pid,而后执行子进程,因为子进程中没有子进程所以返回0,以上就是为什么fork()调用一次执行两次了,执行的两次是在不同的进程中执行的。
2、fork()excu函数族
fork()函数“复制”一个与父进程基本相同的子进程,这两个进程做着同样的事情,然后通过在子进程中调用excu函数族,加载子程序,完成对子进程的替换,这里虽然说是替换但子进程的进程号并没有改变。
3、exec函数族的说明:原文连接
exec函数族装入并运行程序path/file,并将参数arg0(arg1, arg2, argv[], envp[])传递给子程序,出错返回-1.
在exec函数族中,后缀l、v、p、e指定函数将具有某种操作能力:
后缀 | 操作能力 |
l | 希望接收以逗号分隔的参数列表,列表以NULL指针作为结束标志 |
v | 希望接收到一个以NULL结尾的字符串数组的指针 |
p | 是一个以NULL结尾的字符串数组指针,函数可以DOS的PATH变量查找子程序文件 |
e | 函数传递指定参数envp,允许改变子进程的环境,无后缀e时,子进程使用当前程序的环境 |
4、进程间的通讯
1)通过两个进程对一个文件的读写完成通讯
5、exit()函数:表示退出目前的进程,exit(arg) arg==0表示正常退出,不为零表示错误退出
#include <iostream>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
using namespace std;
char command[256];
int main(){
int file_descriptors[2];
pid_t pid;
char buf[256];
int return_size;
pipe(file_descriptors);
if((pid = vfork()) == -1){
printf("Error in fork/n");
exit(1);
}
if(pid == 0){
printf("this is child process,and PID is %d\n",getpid());
fgets(buf,256,stdin);
close(file_descriptors[0]);
write(file_descriptors[1],buf,sizeof(buf));
exit(0);
}
else{
printf("this is parent process,PID is %d, the child PID is %d\n",getppid(),pid);
close(file_descriptors[1]);
return_size = read(file_descriptors[0],buf,sizeof(buf));
printf("recive the data form child process is %s,the bytes is %d\n",buf,return_size);
exit(0);
}
}