Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C fork()的用途是什么?_C_Unix_Posix_Fork - Fatal编程技术网

C fork()的用途是什么?

C fork()的用途是什么?,c,unix,posix,fork,C,Unix,Posix,Fork,在Linux的许多程序和手册页中,我看到了使用fork()的代码。我们为什么需要使用fork()及其目的是什么?fork()将创建一个与父进程相同的新子进程。因此,在此之后在代码中运行的所有内容都将由两个进程运行—如果您有一台服务器,并且希望处理多个请求,这将非常有用。fork()是Unix创建新进程的方式。在您调用fork()时,您的进程被克隆,两个不同的进程从此处继续执行。其中一个子类将使用fork()返回0。另一个是父进程,它将让fork()返回子进程的PID(进程ID) 例如,如果在sh

在Linux的许多程序和手册页中,我看到了使用
fork()
的代码。我们为什么需要使用
fork()
及其目的是什么?

fork()将创建一个与父进程相同的新子进程。因此,在此之后在代码中运行的所有内容都将由两个进程运行—如果您有一台服务器,并且希望处理多个请求,这将非常有用。

fork()是Unix创建新进程的方式。在您调用fork()时,您的进程被克隆,两个不同的进程从此处继续执行。其中一个子类将使用fork()返回0。另一个是父进程,它将让fork()返回子进程的PID(进程ID)

例如,如果在shell中键入以下命令,shell程序将调用fork(),然后在子进程中执行您传递的命令(在本例中为telnetd),而父进程将再次显示提示以及一条指示后台进程PID的消息

$ telnetd &
至于你创建新进程的原因,那就是你的操作系统可以同时做很多事情的原因。这就是为什么您可以运行一个程序,并在程序运行时切换到另一个窗口并执行其他操作。

fork()
是在Unix中创建新进程的方法。当您调用
fork
时,您正在创建自己的流程的副本,该流程有自己的流程。这允许多个任务彼此独立运行,就像它们各自拥有机器的全部内存一样

下面是
fork
的一些示例用法:

  • 使用
    fork
    运行从命令行调用的程序
  • 像这样的Web服务器使用
    fork
    创建多个服务器进程,每个进程在自己的地址空间中处理请求。如果一个内存死亡或泄漏,其他内存则不受影响,因此它起到容错机制的作用
  • 使用
    fork
    在单独的进程中处理每个页面。这将防止一个页面上的客户端代码导致整个浏览器崩溃
  • fork
    用于在某些并行程序中生成进程(如使用编写的程序)。注意这与使用不同,后者没有自己的地址空间并且存在于进程中
  • 脚本语言使用
    fork
    间接启动子进程。例如,每次使用Python中的命令时,都会
    fork
    一个子进程并读取其输出。这使程序能够协同工作
  • shell中
    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]