提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、fork()初识?
1,fork系统调用用于创建一个新进程,称为子进程,它与进程(称为系统调用fork的进程)同时运行,此进程称为父进程。创建新的子进程后,两个进程将执行fork()系统调用之后的下一条指令。子进程使用相同的pc(程序计数器),相同的CPU寄存器。
2,新创建的子进程几乎但不完全与父进程相同,子进程得到与父进程用户级别虚拟地址空间相同的(但是独立的)一份副本,包括代码和数据段,堆,共享库以及用户栈。父进程在调用fork时,子进程可以读写父进程中打开的任何文件。
3,fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,这两个进程可以做完全相同的事
二、例子讲解
1.简单的一个例子:
代码如下(示例):
void fork0()
{
if (fork() == 0) {
printf("Hello from child\n");
}
else {
printf("Hello from parent\n");
}
}
分析:
输出的结果是:
Hello from parent
Hello form child
执行到if(fork()=0)这个语句的时候,变成了两个进程在执行,fork返回0的时候代表进行的是子进程,子进程输出结果是:Hello from parent,父进程执行输出的是:Hello form child。
int main()
{
pid_t pid;
int x = 1;
pid=Fork();
if(pid ==0){ /*Child*/
printf("child : x=%d\n",++x);
exit(0);
}
/*Parent*/
printf("parent: x=%d\n",--x);
exit(0);
}
运行结果是:
parent: x=0
child: x =2
这两个例子中的执行父进程和子进程的那个控制量的返回值不同。因为:fork函数调用一次,返回两次有两个返回:如果返回值是0,则进行子进程;返回的值大于0的数,则进行父进程。
在初学fork函数时,画进程图会有所帮助
第二个例子的进程图:
2.其他例子
代码如下(示例):
int main()
{
if (Fork()==0){
printf("a"); fflush(stdout);
}
else{
printf("b"); fflush(stdout);
waitpid(-1,NULL,0);
}
printf("c"); fflush(stdout);
exit(0);
}
这个程序可能输出的序列是:acbc,abcc,bacc。
在一个进程中可以通过调用waitpid函数来等待它的子进程终止或者停止。
pid_t waitpid(pid_t pid,int *statup,int options);
在默认的情况下(options=0时),waitpid挂起调用进程的执行,直到它的等待集合中的一个子进程终止,如果等待集合中的一个进程在刚调用的时候就已经终止了,那么waitpid就立刻返回。
等待集合的成员由参数pid来确定的:
- 若pid>0,那么等待集合就是一个子进程
- 若pid=-1,那么等待集合就是由父进程所有的子进程组成的。
当正常返回的时候,waitpid返回收集到的子进程的进程ID;
当调用的子进程不存在,waitpid返回-1,这时errno被设置为ECHILD;当waitpid函数被一个信号中断,那么它返回-1,设置errno为EINTR。
总结
fork函数控制进程,fork调用一次,返回两次,子进程和父进程同时执行。
参考:
深入理解计算机系统课本