C fork()的用途是什么?
在Linux的许多程序和手册页中,我看到了使用C fork()的用途是什么?,c,unix,posix,fork,C,Unix,Posix,Fork,在Linux的许多程序和手册页中,我看到了使用fork()的代码。我们为什么需要使用fork()及其目的是什么?fork()将创建一个与父进程相同的新子进程。因此,在此之后在代码中运行的所有内容都将由两个进程运行—如果您有一台服务器,并且希望处理多个请求,这将非常有用。fork()是Unix创建新进程的方式。在您调用fork()时,您的进程被克隆,两个不同的进程从此处继续执行。其中一个子类将使用fork()返回0。另一个是父进程,它将让fork()返回子进程的PID(进程ID) 例如,如果在sh
fork()
的代码。我们为什么需要使用fork()
及其目的是什么?fork()将创建一个与父进程相同的新子进程。因此,在此之后在代码中运行的所有内容都将由两个进程运行—如果您有一台服务器,并且希望处理多个请求,这将非常有用。fork()是Unix创建新进程的方式。在您调用fork()时,您的进程被克隆,两个不同的进程从此处继续执行。其中一个子类将使用fork()返回0。另一个是父进程,它将让fork()返回子进程的PID(进程ID)
例如,如果在shell中键入以下命令,shell程序将调用fork(),然后在子进程中执行您传递的命令(在本例中为telnetd),而父进程将再次显示提示以及一条指示后台进程PID的消息
$ telnetd &
至于你创建新进程的原因,那就是你的操作系统可以同时做很多事情的原因。这就是为什么您可以运行一个程序,并在程序运行时切换到另一个窗口并执行其他操作。fork()
是在Unix中创建新进程的方法。当您调用fork
时,您正在创建自己的流程的副本,该流程有自己的流程。这允许多个任务彼此独立运行,就像它们各自拥有机器的全部内存一样
下面是fork
的一些示例用法:
fork
运行从命令行调用的程序fork
创建多个服务器进程,每个进程在自己的地址空间中处理请求。如果一个内存死亡或泄漏,其他内存则不受影响,因此它起到容错机制的作用fork
在单独的进程中处理每个页面。这将防止一个页面上的客户端代码导致整个浏览器崩溃fork
用于在某些并行程序中生成进程(如使用编写的程序)。注意这与使用不同,后者没有自己的地址空间并且存在于进程中fork
间接启动子进程。例如,每次使用Python中的命令时,都会fork
一个子进程并读取其输出。这使程序能够协同工作fork
的典型用法可能如下所示:
int child_process_id = fork();
if (child_process_id) {
// Fork returns a valid pid in the parent process. Parent executes this.
// wait for the child process to complete
waitpid(child_process_id, ...); // omitted extra args for brevity
// child process finished!
} else {
// Fork returns 0 in the child process. Child executes this.
// new argv array for the child process
const char *argv[] = {"arg1", "arg2", "arg3", NULL};
// now start executing some other program
exec("/path/to/a/program", argv);
}
shell使用exec
生成一个子进程,并等待它完成,然后继续自己的执行。注意,您不必这样使用fork。您总是可以派生出许多子进程,就像一个并行程序可能做的那样,每个子进程都可以并发运行一个程序。基本上,每当您在Unix系统中创建新进程时,您都在使用fork()
。对于Windows等价物,请查看
如果你想要更多的例子和更长的解释,有一个像样的总结。这里介绍了进程、线程和并发在现代操作系统中的工作方式。fork()用于创建子进程。调用fork()函数时,将生成一个新进程,fork()函数调用将为子进程和父进程返回不同的值
如果返回值为0,则表示您是子进程;如果返回值为数字(正好是子进程id),则表示您是父进程。(如果是负数,则fork失败,并且没有创建子进程)
fork()
用于生成子进程。通常,它在与线程类似的情况下使用,但也有不同之处。与线程不同,fork()
创建整个分离的进程,这意味着子进程和父进程在调用fork()
时是彼此的直接副本,但它们是完全分离的,都不能访问另一个进程的内存空间(在不出现正常故障的情况下,您可以访问另一个程序的内存)
fork()
仍被一些服务器应用程序使用,大多数是在*NIX机器上以root用户身份运行的应用程序,在处理用户请求之前会放弃权限。还有一些其他使用情况,但大多数人现在已经转向多线程。多处理是计算的核心。例如,您的IE或Firefox可以创建一个要执行的进程当您仍在浏览internet时为您加载文件。或者,当您在文字处理器中打印文档时,您仍可以查看不同的页面并对其进行编辑。fork()基本上用于为调用此函数的进程创建子进程。每当您调用fork()时,则子id返回零。pid=fork()
if pid==0
//this is the child process
else if pid!=0
//this is the parent process
这样,您可以为父级和子级提供不同的操作,并利用多线程功能。如果您正在编写应用程序,您可能不需要在日常编程中使用fork 即使您确实希望您的程序启动另一个程序来执行某些任务,也有其他更简单的界面在幕后使用fork,例如C和perl中的“system” 例如,如果您希望您的应用程序启动另一个程序(如bc)来为您执行一些计算,您可以使用“系统”来运行它。系统执行“fork”来创建新进程,然后执行“exec”将该进程转换为bc。bc完成后,系统将控制权返回给您的程序 您也可以异步运行其他程序,但我不记得如何运行
如果您正在编写服务器、shell、病毒或操作系统,则更可能希望使用fork。fork会创建新进程。如果没有fork,您的unix系统将只能使用fork
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
int main()
{
int t1,t2,p,i,n,ab;
p=getpid();
printf("enter the number of levels\n");fflush(stdout);
scanf("%d",&n);
printf("root %d\n",p);fflush(stdout);
for(i=1;i<n;i++)
{
t1=fork();
if(t1!=0)
t2=fork();
if(t1!=0 && t2!=0)
break;
printf("child pid %d parent pid %d\n",getpid(),getppid());fflush(stdout);
}
waitpid(t1,&ab,0);
waitpid(t2,&ab,0);
return 0;
}
enter the number of levels
3
root 20665
child pid 20670 parent pid 20665
child pid 20669 parent pid 20665
child pid 20672 parent pid 20670
child pid 20671 parent pid 20670
child pid 20674 parent pid 20669
child pid 20673 parent pid 20669
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#define MAX_COUNT 200
#define BUF_SIZE 100
void main(void)
{
pid_t pid;
int i;
char buf[BUF_SIZE];
fork();
pid = getpid();
for (i = 1; i <= MAX_COUNT; i++) {
sprintf(buf, "This line is from pid %d, value = %d\n", pid, i);
write(1, buf, strlen(buf));
}
}
pid = .....;
................
This line is from pid 3456, value 13
This line is from pid 3456, value 14
................
This line is from pid 3456, value 20
This line is from pid 4617, value 100
This line is from pid 4617, value 101
................
This line is from pid 3456, value 21
This line is from pid 3456, value 22
................
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
int var_glb; /* A global variable*/
int main(void)
{
pid_t childPID;
int var_lcl = 0;
childPID = fork();
if(childPID >= 0) // fork was successful
{
if(childPID == 0) // child process
{
var_lcl++;
var_glb++;
printf("\n Child Process :: var_lcl = [%d], var_glb[%d]\n", var_lcl, var_glb);
}
else //Parent process
{
var_lcl = 10;
var_glb = 20;
printf("\n Parent process :: var_lcl = [%d], var_glb[%d]\n", var_lcl, var_glb);
}
}
else // fork failed
{
printf("\n Fork failed, quitting!!!!!!\n");
return 1;
}
return 0;
}
$ ./fork
Parent process :: var_lcl = [10], var_glb[20]
Child Process :: var_lcl = [1], var_glb[1]