V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
AkideLiu
V2EX  ›  C

C 紫禁城 Fork(), execvp 是个啥?好难找到资料啊

  •  
  •   AkideLiu · Apr 4, 2021 · 4147 views
    This topic created in 1861 days ago, the information mentioned may be changed or developed.

    搜了搜比较有价值的是这一篇

    https://ece.uwaterloo.ca/~dwharder/icsrts/Tutorials/fork_exec/

    
    #include <stdio.h>
    
    /* This program forks and and the prints whether the process is
     *   - the child (the return value of fork() is 0), or
     *   - the parent (the return value of fork() is not zero)
     *
     * When this was run 100 times on the computer the author is
     * on, only twice did the parent process execute before the
     * child process executed.
     *
     * Note, if you juxtapose two strings, the compiler automatically
     * concatenates the two, e.g., "Hello " "world!"
     */
    
    int main( void ) {
    	char *argv[3] = {"Command-line", ".", NULL};
    
    	int pid = fork();
    
    	if ( pid == 0 ) {
    		execvp( "find", argv );
    	}
    
    	/* Put the parent to sleep for 2 seconds--let the child finished executing */
    	wait( 2 );
    
    	printf( "Finished executing the parent process\n"
    	        " - the child won't get here--you will only see this once\n" );
    
    	return 0;
    }
    
    

    Stack Overflow 上很少有人讨论这个话题,有大佬能发一下资料吗

    18 replies    2021-04-04 17:16:18 +08:00
    kokutou
        1
    kokutou  
       Apr 4, 2021
    你这里面不是写的很清楚了...
    GeruzoniAnsasu
        2
    GeruzoniAnsasu  
       Apr 4, 2021
    21 天前回复了 hm20062006ok 创建的主题 › Google › 怎样让搜索引擎更好的理解我的需求?
    如果用 Google,可以多看看 stackoverflow 的问题是怎么提的,多学学就好了

    ----------

    ... fork() 这种基础问题百度都能搜到,别说 google 了,不懂你想找的资料是啥
    AkideLiu
        3
    AkideLiu  
    OP
       Apr 4, 2021
    @kokutou 恩 demo 写的不是很复杂,注释解释的也很清晰。

    但是还是不太懂这段代码实际运行的逻辑。

    我的理解是这样的,例子里面从 main 里面拆出来一个 child 去执行命令行操作,parent 部分在 child 运行完成再运行,那这样做的意义在哪里呢?

    如果我想多次执行多组命令的话是使用多次 fork 来实现吗?
    wjm2038
        4
    wjm2038  
       Apr 4, 2021 via Android
    man fork
    man execvp
    ipwx
        5
    ipwx  
       Apr 4, 2021
    @AkideLiu fork 和 exec 都是 posix 操作系统的概念。实际上 windows 是不支持这两个操作的。。。

    这不是 C 语言的知识,是操作系统的知识。
    ch2
        6
    ch2  
       Apr 4, 2021 via iPhone   ❤️ 1
    这个是 c 语言的 unistd 库的内容,它其实是操作系统的特性,准确的说都是 syscall 系统调用的包装。你想学这个直接学 Linux 进程模型就是了,manpages 里有针对每个系统调用对应的函数的详细说明
    ipwx
        7
    ipwx  
       Apr 4, 2021   ❤️ 1
    @AkideLiu

    我的理解是这样的,例子里面从 main 里面拆出来一个 child 去执行命令行操作,parent 部分在 child 运行完成再运行,那这样做的意义在哪里呢?
    ====

    意义很多。主要是你没有写过这样的程序。比如我想运行一个外部命令,但是要截获所有它的输出。fork + exec 的做法就是父进程在 fork 前用 pipefd 先打开一个管道,由于 fork 以后子进程和父进程在最初共享所有文件描述符,所以子进程往管道一头写,父进程就能在另一头读到。接着用 dup2 用 pipefd 替换掉标准 stdout 和 stderr,这样就能让子进程的标准输出和错误输出都直接定向到管道。最后用 exec 让某个命令代替目前的程序在当前进程号(以及这个 pipefd 顶替掉 stdout 和 stderr 的上下文)中运行。

    这么一操作,父进程就能直接从管道读到这个命令的输出了。

    https://stackoverflow.com/questions/2605130/redirecting-exec-output-to-a-buffer-or-file
    AkideLiu
        8
    AkideLiu  
    OP
       Apr 4, 2021
    @ch2
    @ipwx

    谢谢两位的解答。通过两位的回答大概是要好好看看进程调用和 IO 原理这一块了。

    ------

    看完这个例子,我好想明白一点。就是说如果只有一个 main 进程是没办法 synchronized stdout 到多个不同的 buffer 或者 file 的,通过 fork 出来 child 可以实现这一点。child 负责执行,parent 负责处理最终结果(如果需要的话,比如 pipe)
    mingl0280
        9
    mingl0280  
       Apr 4, 2021 via Android
    man exec 有详细解释啊……
    err1y
        10
    err1y  
       Apr 4, 2021 via iPhone
    建议系统的看一下《 unix 环境高级编程》这本书,或者当工具书查也行
    sarvatathagata
        11
    sarvatathagata  
       Apr 4, 2021
    想起 kill 紫禁城那个笑话了
    ManjusakaL
        12
    ManjusakaL  
       Apr 4, 2021 via iPhone
    建议看一下 Unix 环境高级编程
    iseki
        14
    iseki  
       Apr 4, 2021 via Android   ❤️ 2
    看了半天没明白 “紫禁城 fork” 是什么东西,敢情是子进程…
    lance6716
        15
    lance6716  
       Apr 4, 2021 via Android
    @AkideLiu 有的资源(以 stdout 为例)是每个进程只能有一份的,fork 之后是两个进程,所以就能用各自的了。这种资源还有内存啊之类的

    与此带来的就是,既然两个进程是各自“独立”的资源,进程通信就要找别的办法
    carlclone
        16
    carlclone  
       Apr 4, 2021 via Android
    今天 6s081 才刚看到这个,太巧了,刚好说到为什么不是 forkexec 而是 fork+exec,楼上已经解释得很清楚了
    irytu
        17
    irytu  
       Apr 4, 2021 via iPhone
    比如允许你进行 IO 重定向,去学学 6.828 或者 6.S081 吧
    no1xsyzy
        18
    no1xsyzy  
       Apr 4, 2021
    IIRC,还有一种用途,nginx 多个 worker 进程同时监听一个端口,用 fork 来共享 fd (打开的网络端口也是 fd )
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2963 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 104ms · UTC 14:58 · PVG 22:58 · LAX 07:58 · JFK 10:58
    ♥ Do have faith in what you're doing.