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函數的用戶的進程太多。
