fork创建进程
函数原型如下
#include// 必须引入头文件,使用fork函数的时候,必须包含这个头文件,否则,系统找不到fork函数
pid_t fork(void); //void代表没有任何形式参数
父进程与子进程
1.掌握概念,什么是父进程,什么是子进程
除了0号进程(系统创建的)之外,linux系统中都是由其他进程创建的。创建新进程的进程,即调用fork函数的进程为父进程,新建的进程为子进程。
2.fork函数不需要任何参数,对于返回值有三种情况
1)对于父进程,fork函数返回新建子进程的pid;
2)对于子进程,fork函数返回 0;
3)如果出错, fork 函数返回 -1。
创建进程案例(fork.c)
#include
#include
#include
int main(void)
{
pid_t pid ;
pid = fork();
if(pid < 0)
{
printf("fail to fork\n");
exit(1);
}
if(pid == 0)
{
printf("this is the child,pid is : %u\n",getpid());
exit(0);
}
if(pid > 0)
{
printf("this is the parent\n");
exit(0);
}
return 0;
}
在shell中编译该程序如下:
gcc fork.c -o fork
在shell中运行该程序如下:
./fork
最后输出结果:
再次运行结果如下:
父子进程共享资源
1.父子进程共享代码段(可读的)
父进程在创建子进程的时候,子进程会把父进程的地址空间里的数据段。和栈堆进行复制,但是没有复制代码段。
2.详细可看具体代码示例(fork_1.c)
fork_1.c
#include
#include
#include
int global; // 全局变量在数据段中
int main()
{
pid_t pid;
int stack = 1; // 局部变量在栈中
int * heap;
heap = (int *)malloc(sizeof(int)); //在堆中
*heap = 2;
pid = fork();
if(pid < 0)
{
printf( " fail to fork\n " ) ;
exit(1) ;
}
if( pid == 0 )
{
global++ ;
stack ++ ;
(*heap)++ ;
printf ( " the child , data : %d , stack : %d , heap : %d\n", global , stack , * heap ) ;
exit(0) ;
}
sleep(2) ;
printf("the parent, data : %d, stack : %d, heap : %d\n", global , stack , *heap);
return 0 ;
}
运行结果如下:
fork函数出错的情况
1.fork函数返回值为-1即创建失败,有两种情况可能会导致fork 函数出错;
2.系统中已经有太多的进程存在;
3.调用fork函数的用户的进程太多。