详细请点击:http://www.verydemo.com/demo_c170_i14063.html
刚刚进入UNIX进程处理的一部分,感觉比前边的难度大了许多,
切入正题
UNIX内核开启一个新进程的唯一方法是利用已有的进程fork
函数原型
#include<sys/types.h>
#include<unistd.h>
pid_t fork(void)
fork函数调用一次,返回两次。在子进程中返回0,父进程中返回子进程的进程ID。父子进程将从fork处继续执行,子进程将从父进程处得到其一份数据区、堆栈的拷贝,它们并不共享内存区域。但在目前大多数的平台上并不是完全的拷贝,而是采用COW(copy-on-write)技术。当父子进程中某个需要修改内存区时,它将得到一份所要修改的内存区的拷贝。
在使用fork时,要注意 阻塞与非阻塞
Eep
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<myerror.h>
int glob=6;
char buf[]="a write to stdout\n";
int main(void)
{ int var;
pid_t pid;
var =88;
if(write(STDOUT_FILENO,buf,sizeof(buf)-1)!=sizeof(buf)-1)
err_sys("write error");
printf("before fork\n");
if((pid=fork())<0)
err_sys("fork error");
else if(pid==0)
{glob++;
var++;
}else
sleep(2);
printf("pid=%d,glob=%d,var=%d\n",getpid(),glob,var);
exit(0);
)
运行
$a.out
a write to stdout
before fork
pid=430,glob=7,var=89
pid=429,glob=6,var=88
$a.out>temp.out
$cat temp.out
a write to stdout
before fork
pid=432,glob=7,var=89
before fork
pid=431,glob=6,var=88
可以注意到当父进程重定向时,子进程也被重定向
可以导致fork错误的原因:a.系统中进程过多 b.某一个real UID 下的进程数超过了系统设置的上限(CHILD_MAX)
vfork函数
原型
#include<sys/types.h>
#include<unistd.h>
pid_t vfork();
(某些应用调用vfork时需要包含头文件vfork.h)
与fork不同的是vfork产生的子进程与父进程共享内存区域,另一个不同是vfork保证子进程优先运行直到其调用exec或exit(当子进程在调用exit或exec前需要父进程某些操作时,将导致死锁)
Exp
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
int golb =6;
int main(void)
{ int var; /*automatic variable on the stack*/
pid_t pid;
var=88;
printf("before vfork\n"); /*we don't flush stdio*/
if((pid=vfork())<0)
err_sys("vfork error");
else if(pid==0)
{ glob++;
var++;
_exit(0);
}
printf("pid=%d,glob=%d,var=%d\n",getpid(),glob,var);
exit(0);
)
运行
$a.out
befork vfork
pid=607,glob=7,var=89