V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
AkideLiu
V2EX  ›  C

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

  •  
  •   AkideLiu · 2021-04-04 00:50:01 +08:00 · 3394 次点击
    这是一个创建于 1332 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    ----------

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

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

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

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

    这不是 C 语言的知识,是操作系统的知识。
    ch2
        6
    ch2  
       2021-04-04 02:14:21 +08:00 via iPhone   ❤️ 1
    这个是 c 语言的 unistd 库的内容,它其实是操作系统的特性,准确的说都是 syscall 系统调用的包装。你想学这个直接学 Linux 进程模型就是了,manpages 里有针对每个系统调用对应的函数的详细说明
    ipwx
        7
    ipwx  
       2021-04-04 02:14:55 +08:00   ❤️ 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
       2021-04-04 02:43:10 +08:00
    @ch2
    @ipwx

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

    ------

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

    与此带来的就是,既然两个进程是各自“独立”的资源,进程通信就要找别的办法
    carlclone
        16
    carlclone  
       2021-04-04 16:15:13 +08:00 via Android
    今天 6s081 才刚看到这个,太巧了,刚好说到为什么不是 forkexec 而是 fork+exec,楼上已经解释得很清楚了
    irytu
        17
    irytu  
       2021-04-04 16:58:58 +08:00 via iPhone
    比如允许你进行 IO 重定向,去学学 6.828 或者 6.S081 吧
    no1xsyzy
        18
    no1xsyzy  
       2021-04-04 17:16:18 +08:00
    IIRC,还有一种用途,nginx 多个 worker 进程同时监听一个端口,用 fork 来共享 fd (打开的网络端口也是 fd )
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1005 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 21:38 · PVG 05:38 · LAX 13:38 · JFK 16:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.