赞
踩
一个现存进程调用fork函数是UNIX内核创建一个新进程的唯一方法。通过fork创建的新进程被称作为子进程。 fork函数被调用一次,但是返回两次。其中子进程的返回值是0,而父进程的返回值则是新创建的子进程的进程PID。 将子进程的pid作为父进程的返回值的原因是:一个进程的子进程有多个,没有一个函数使一个进程可以获得所有的子进程的pid。fork之后子进程的fork函数返回值是0的原因:一个进程智能有一个父进程,所以子进程总是可以调用getpid来获取父进程的进程id,所以子进程的进程id不可能为0.
父进程和子进程是继续执行fork之后的指令。父进程是子进程的复制品:子进程获取父进程的数据空间、堆和栈的复制品。 此外,子进程和父进程的数据空间、堆、栈都是独立的空间,互不干扰。
当然,考虑到了节省空间和效率等等方面,现在可以使用写时拷贝技术(Copy-On-Write) 来提高fork和exec的效率。对于父进程的数据段和堆,父子进程共享这块空间,这即省去了再从新开辟空间并且复制的开销。等到有进程来尝试修改这块空间的时候,则对这块空间再进行一个拷贝,然后让进程进行修改。
一般来说,在fork之后,父进程和子进程谁先执行是不确定的,同一段可执行程序多运行几次可发现子进程和父进程会交替先执行,这取决于内核的调度算法。如果要求父子进程同步运行,则需要一定的进程间通信来达到要求。
当数据在缓存区中的时候,调用fork函数时,缓冲区中的数据也会被复制到子进程中。 所以,父子进程都会都自带了该缓冲区中的内存数据。得到结论:fork会把所有父进程打开的描述符都复制到子进程中。
父子进程每个相同的打开描述符共享同一个文件表项。 如果一个进程打开了三个不同的标准文件:标准输入(fd=0),标准输出(fd=1),标准出错(fd=2)。则:
fork在计算机中的主要用法之一便是:一个进程复制自己,使得子进程去处理网络服务请求,父进程继续等到下一个服务请求。另一个用途:子进程去执行不同的程序。
fork的两个失败原因:
vfork和fork的调用基本相同。但是,vfork的目的是创建一个新进程,新进程的目的是exec一个新程序。vfork也会创建一个子进程,但是不把父进程的地址空间完全复制道子进程之中,因为子进程会立即调用exec,在调用exec之前,在父进程的空间中运行。此外,vfork会保证子进程先运行,在子进程调用exec或者exit之后,父进程才会被调度。 所以,vfork不安全,因为两者共用父进程的同一块地址空间,而子进程则可能会修改这部分的数据,等到父进程运行的时候,则可能会发现数据被修改了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。