Linux中的fork函数
操作系统实验二
fork函数
作用
fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程
返回值
- 负值:创建子进程失败。
- 零:返回到新创建的子进程。
- 正值:返回父进程或调用者。该值包含新创建的子进程的进程ID
用法
pid_t pid=fork();
如果创建成功,会有两个进程:父进程和子进程,fork在这两个进程中分别返回,就是返回两次且返回值不同。
一段程序
# include<stdio.h>
# include<sys/types.h>
# include<unistd.h>
int main()
{
int pid1, pid2;
printf("I am father %d! My father is %d.\n", getpid(), getppid());
if ((pid1 = fork())<0) //fork return value < 0 , create failed
{
printf("Child1 fail create!\n");
return 1;
}
else if (pid1 == 0) //fork return value = 0, son is running
{
printf("I am son %d! My father is %d. \n", getpid(), getppid());
return 0;
}
if ((pid2 = fork())<0)
{
printf("Child2 fail create!\n");
return 0;
}
else if (pid2 == 0)
{
printf("I am daughter %d! My father is %d.\n", getpid(), getppid());
return 0;
}
}
编译运行
gcc fork.c -o fork
./fork
运行结果
分析: 首先是父进程,打印了它的身份和进程号,还有它的父进程号
在第一个if语句中创建了子进程,子进程创建成功,返回值是0,执行第一个else if,打印身份是子进程和它的进程号和父进程号。
父进程的fork返回值是子进程号大于0,不满足第一个条件,顺序往下执行,在第二个if里创建了一个进程。
子进程创建成功,返回值是0,执行else if,打印身份、进程号和父进程号。
daughter进程的父进程号时884,是因为父进程已经运行结束了,daughter进程找不到原来的父进程,变成了孤儿进程,被其他进程收养了。
分析: 有时daughter进程和son进程顺序不一样是因为父进程比son进程执行的快,先创建了daughter进程,daughter进程先进行了打印。
打印在命令行上的原因:
处理父进程、son进程、daughter进程,还有一个shell进程,shell进程就是用户和linux交互的进程,用于解析输入的命令行。这四个进程都要抢占屏幕这个资源,如果被shell先抢占了,就会出现命令行,其他进程输出就会在命令行上了。(不知道理解的对不对。。。)
孤儿进程
父进程运行结束后,它创建的子进程还在运行,这些子进程就会成为孤儿进程。
避免出现孤儿进程: 在父进程运行最后加上sleep(1)
,父进程不会运行那么快,保证子进程先退出。
lockf函数
参考:https://blog.csdn.net/qq_24421591/article/details/49104455
用处
实现资源的互斥访问
例子
# include<stdio.h>
# include<sys/types.h>
# include<unistd.h>
int main(){
int pid1, pid2;
pid1=fork();
if(pid1 == 0)
{
for(int i = 0; i < 5; i ++ )
{
lockf(1,1,0); //加锁
printf("I am son %d\n",i);
lockf(1,0,0); //解锁
sleep(3); //等待3s
}
}
else
{
pid2=fork();
if(pid2 == 0)
{
for(int i = 0; i < 5; i ++ )
{
lockf(1,1,0);
printf("I am daughter %d\n",i);
lockf(1,0,0);
sleep(3);
}
}
else
{
printf("I am father\n");
}
}
return 0;
}
分析: 临界资源是屏幕,son进程和daughter进程会交替打印,是因为在循环中打印过后,会等待3s,在等待的时间里,另一个进程就是抢占资源,进行打印。
对比
将sleep(1)放在解锁之前,这样即使进程在sleep,其他进程也没有机会抢占资源。