In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/02 Report--
This article shares a simple comparative analysis of Linux vfork and fork, which is as follows:
Questions related to fork:
1. Basic understanding of fork
The function of fork is to create a child process. After using the fork command, the kernel allocates new memory blocks and data structures to the child process, and copies part of the data structure contents of the parent process to the child process. Finally, the child process is added to the list of system processes. After the addition is completed, the fork returns and starts scheduling.
Header file: # include
< unistd.h >Function prototype: pid_t fork ()
Return value: if the return value is greater than 0, the current process is the parent process, equal to 0 is the child process, and less than zero means the creation of the child process failed.
Use an example to understand:
# include # include int main () {int tmp = 5; pid_t res = fork (); if (res
< 0){ //fork失败 perror("fork"); }else if(res == 0){ //该进程为子进程 printf("im child[%d],fasther is %d,tmp is %d.\n",getpid(),getppid(),tmp++); }else{ //该进程为父进程 printf("im father[%d],tmp is %d.\n",getpid(),tmp++); } printf("tmp = %d\n",tmp); return 0; } 运行结果: im father[3128],tmp is 5. tmp = 6 im child[3129],fasther is 1,tmp is 5. tmp = 6 相关问题小结: 通过结果很明显的能看出本次调用中,先执行父进程,对应pid为3128,在父进程中tmp++,所以输出为6;关键问题在于子进程,有两个关键点。 ①为什么结果中子进程父亲pid为1:通过输出我们能看出父进程先执行完成后才执行的子进程,也就是说当子进程执行时父进程已结束,此时该子进程相当于一个孤儿进程,被pid为1也就是Init进程所管理,所以子进程的ppid为1; ②为什么子进程最后输出tmp值还为6: fork进程采用的是写时拷贝,父子进程一开始共享一片内存区域,但是只有有一方要对数据进行修改,则再开辟一块空间,防止相互修改影响。所以在上述代码中,虽说是一个tmp,其实内存中各自保留了一份值。 二、关于fork过程中写时拷贝: 这下就不难看出,父子进程数据段和代码段开始时是共享一块对应的内存,当一方尝试写入时,便产生了写时拷贝。需要注意的是:fork之前,父进程独立执行,fork之后,父子两个执行流分别执行,至于谁先执行,由调度器决定。可通过下面例子很明显的看出是从fork之后才分别执行。 #include #include int main() { int tmp = 5; printf("There is fork before\n"); pid_t res = fork(); if(res < 0){ //fork失败 perror("fork"); }else if(res == 0){ //该进程为子进程 printf("im child[%d],tmp is %d.\n",getpid(),tmp++); }else{ //该进程为父进程 printf("im father[%d],tmp is %d.\n",getpid(),tmp++); } printf("tmp = %d\n",tmp); return 0; } 输出结果: There is fork before im father[3625],tmp is 5. tmp = 6 im child[3626],tmp is 5. tmp = 6 三、fork调用失败的原因: ①系统中已经存在太多进程,无法再创建新的进程。可通过ulimit -a命令查看当前所有的资源限制。 ②内存不足,由于开辟每个新的进程都要分配一个PCB,并为新进程分配资源,内存都不足也就别提还想着再创建进程了。 vfork相关问题: 一、vfork基础了解 vfork创建新进程的主要目的在于用exec函数执行另外的程序,实际上,在没调用exec或_exit之前子进程与父进程共享数据段。在vfork调用中,子进程先运行,父进程挂起,直到子进程调用exec或_exit,在这以后,父子进程的执行顺序不再有限制。 头文件:#include < unistd.h >Function prototype: pid_t vfork ()
Return value: if the return value is greater than 0, the current process is the parent process, equal to 0 is the child process, and less than zero means the creation of the child process failed.
Use an example to understand:
# include # include int tmp = 3; int main () {pid_t res = vfork (); if (res < 0) {perror ("vfork"); _ exit ();} else if (res = = 0) {tmp = 10; printf ("child res =% d\ n", tmp); _ exit (0);} else {printf ("father res =% d\ n", tmp);} return 0;}
Output result:
Child res = 10
Father res = 10
Result analysis: as mentioned above, the child process directly shares the page table of the parent process, and changing the data of the child process will also affect the parent process.
The purpose of vfork:
Vfork () is similar to fork () in that it creates a child process, and the return values of both functions have the same meaning. But basically, the child process created by vfork () can only do one thing, and that is to call the _ exit () function or a member of the exec function family immediately, call any other function (including exit ()), modify any data (except the variable that holds the return value of vfork ()), and execute any other statements (including return). What's more important is that after calling vfork (), the parent process blocks until the child process calls _ exit () to terminate, or calls a member of the exec function family.
Why you can only exit with _ exit:
Exit () is an encapsulation of _ exit (). It does a lot of cleaning work before calling _ exit (), including refreshing and closing the flow cache used by the current process (such as printf in stdio.h). Because the child process of vfork () completely shares the address space of the parent process, and the stream in the child process is also the stream of the shared parent process, these things cannot be done in the child process. Direct return is even worse. After the return, the child process will continue to execute from the external call point of the current function, which may execute a lot of statements, and the result will be unpredictable. This point is also emphasized in the man manual, which must be exited using _ exit.
The difference between fork and vfork
1.vfork ensures that the child process runs first, and the parent process cannot be scheduled to run until it calls exec or exit. If the child process relies on further actions of the parent process before calling these two functions, it will result in a deadlock.
2.fork needs to copy the process environment of the parent process, while vfork does not need to completely copy the process environment of the parent process. Before the child process does not call exec and exit, the child process shares the process environment with the parent process, which is equivalent to the concept of threads, when the parent process blocks waiting.
Why is there a vfork?
Because the previous fork, when it created a child process, would create a new address space and copy the resources of the parent process, and then there would be two behaviors:
1. Execute code snippets copied from the parent process
two。 Call an exec to execute a new code snippet
When a process calls the exec function, a new program replaces the body, data, heap, and stack segments of the current process. In this way, the previous copy work is in vain, in which case, smart people come up with vfork. Vfork does not copy the process environment of the parent process, and the child process runs in the address space of the parent process, so the child process cannot write, and when the son "occupies" Laozi's house, he will be wronged and let him rest outside (blocking). Once the son has executed exec or exit, the son has bought his own house, which is tantamount to separation.
Therefore, if a child process is created to call exec to execute a new program, you should use vfork
The above is the whole content of this article, I hope it will be helpful to your study, and I also hope that you will support it.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.