fork函数创建进程
1.fork()函数的原型
man手册中fork()函数原型如下:
#include <unistd.h>
pid_t fork(void);
fork中的参数为无类型,返回值为pid_t。
2.fork() 函数的返回值
fork函数调用成功,返回两次
返回值为0,代表当前进程是子进程
返回值为非负数,代表当前进程是父进程
调用失败,返回-1.
编写一段程序,将fork的返回值打印出来,如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
// pid_t fork(void);
int main()
{
pid_t pid;
pid =fork();
if(pid == -1)
{
printf("create fail\n");
exit(-1);
}
printf("create success\n");
printf("pid = %d\n",pid);
}
fork()函数代表创建一个进程,fork()函数之后就会有两个进程在执行下面的程序,但是两个进程在不同的空间,所以互不影响,输出结果有两个的原因也是因为有两个进程,pid =0代表子进程,pid>0代表父进程。
其运行结果如下:
3.fork()函数与getpid()的联合使用(看子进程是否创建成功)
getpid()函数可以获得当前进程的pid号,其函数原型如下:
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
代码如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
// pid_t fork(void);
int main()
{
pid_t pid;
pid_t pid2;
pid =getpid();
pid2=fork();
if( pid2== -1)
{
printf("create fail\n");
exit(-1);
}
printf("pid = %d,getpid()=%d\n",pid,getpid());
}
其运行结果如下:
其中pid和getpid()相等的为父进程,pid和getpid()不等的为子进程,因为父进程一路执行下来,它的pid是不会改变的,而子进程是创建的一个新的进程,pid也应该是新的pid。
4.进程的简介用法
创建进程终究是让它进行工作,而且让其执行与父进程不同的工作,前面我们已经知道了其返回值,所以可以如下进行进程的创建
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
// pid_t fork(void);
int main()
{
pid_t pid;
pid=fork();
if(pid>0)
{
printf("this is father fork\n");
}
else if(pid==0)
{
printf("this is child fork\n");
}
}
根据返回值和0相比的大小来区分父进程和子进程,这样可以让父子进行不同的工作,互相不干扰。
运行结果如下:
5.vfork()函数创建进程
vfork与fork有什么区别
区别一:
vfork直接使用父进程存储空间,不拷贝
区别二:
vfork保证子进程先运行,当子进程调用exit退出后,父进程才执行。
程序如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
// pid_t fork(void);
int main()
{
pid_t pid;
pid=vfork();
int cnt;
if(pid>0)
{
while(1)
{
printf("this is father fork\n");
sleep(1);
printf("cnt=%d\n",cnt);
}
}
else if(pid==0)
{
cnt=0;
while(1)
{ cnt++;
printf("this is child fork\n");
sleep(1);
if(cnt==3)
{
exit(0);
}
}
}
}
其中cnt变量可以验证区别1,cnt的值都是在子进程中完成的,但是在父进程打印和子进程结果相同,说明内存是共享的。执行完子进程父进程才继续执行。
运行结果如下: