fork:系统调用 -> 复制父进程
#include <unistd.h>
#include <stdio.h>
int main() {
pid_t fpid;//fpid表示fork函数返回的值
//printf("fork!");
printf("fork!/n");
fpid = fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0)
printf("child: %d/n", getpid());
else
printf("parent:%d/n", getpid());
return 0;
}
执行结果:
fork!
parent : 3361
child :3362
如果把语句printf("fork!/n");注释掉,执行printf("fork!");
则新的程序的执行结果是:
fork!parent :3298
fork!child :3299
parent : 3361
child :3362
如果把语句printf("fork!/n");注释掉,执行printf("fork!");
则新的程序的执行结果是:
fork!parent :3298
fork!child :3299
分析:
这就跟printf的缓冲机制有关了,printf某些内容时,操作系统仅仅是把该内容放到了stdout的缓冲队列里了,并没有实际的写到屏幕上。但是,只要看到有/n 则会立即刷新stdout,因此就马上能够打印了。
运行了printf("fork!")后,“fork!”仅仅被放到了缓冲里,程序运行到fork时缓冲里面的“fork!” 被子进程复制过去了。因此在子进程度stdout缓冲里面就也有了fork! 。所以,你最终看到的会是fork! 被printf了2次!!!!
而运行printf("fork! /n")后,“fork!”被立即打印到了屏幕上,之后fork到的子进程里的stdout缓冲里不会有fork! 内容。因此你看到的结果会是fork! 被printf了1次!!!!
运行了printf("fork!")后,“fork!”仅仅被放到了缓冲里,程序运行到fork时缓冲里面的“fork!” 被子进程复制过去了。因此在子进程度stdout缓冲里面就也有了fork! 。所以,你最终看到的会是fork! 被printf了2次!!!!
而运行printf("fork! /n")后,“fork!”被立即打印到了屏幕上,之后fork到的子进程里的stdout缓冲里不会有fork! 内容。因此你看到的结果会是fork! 被printf了1次!!!!
eg1:
eg2:
结果:
eg3:
结果:
fork被输出的三种情况:
1.缓冲区放满了
2.没放满,强制刷新("\n")
3.程序结束的时候
pid可唯一标识进程
父进程的fork号是子进程
子进程的fork号是0
写时拷贝:以页为单位
父子进程先是共享代码,当子进程对代码进行修改时,才进行拷贝
父子进程中打印的某个变量的地址是逻辑地址,不是物理地址
在父进程中打开的文件,经过fork复制,在子进程中任然可以访问,父子进程共享文件的偏移量
///
Fork和vfork的区别:
Vfork产生的子进程和父进程完全共享地址空间,包括代码段、数据段和堆栈段,子进程对这些共享资源的修改会影响父进程。So,vfork与其说产生了一个进程,不如说产生了一个线程
Vfork产生的子进程一定会先于父进程运行,父进程调用vfork()后会等待子进程运行后再运行
Linux下用systerm()调用shell指令
#include<stdlib.h>
Int system(const char* cmdstring); //cmdstring是要执行的shell命令
//fork+exec
Eg:system(“ls > tmp.txt”) //使用system命令执行ls命令,并将结果输入到tmp.txt文件
//可以使用shell源字符’>’或’|’
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
int system(const char* cmdstring)
{
pid_t pid;
int status;
if(cmdstring==NULL)
return 1;
pid=fork();
if(pid<0)
status=-1;
else if(pid==0)
{
execl("/bin/sh","sh","-c",cmdstring,NULL); //ti huan zijincheng
_exit(127); //tihuan shibai tuichu zijincheng
}
if(waitpid(pid,&status,0)==-1) //huode zijincheng de tuichuma
status=-1;
return status;
}