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

2021-04-04 00:50:01 +08:00
 AkideLiu

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

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 上很少有人讨论这个话题,有大佬能发一下资料吗

3418 次点击
所在节点    C
18 条回复
kokutou
2021-04-04 00:53:38 +08:00
你这里面不是写的很清楚了...
GeruzoniAnsasu
2021-04-04 01:03:02 +08:00
21 天前回复了 hm20062006ok 创建的主题 › Google › 怎样让搜索引擎更好的理解我的需求?
如果用 Google,可以多看看 stackoverflow 的问题是怎么提的,多学学就好了

----------

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

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

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

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

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

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

------

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

与此带来的就是,既然两个进程是各自“独立”的资源,进程通信就要找别的办法
carlclone
2021-04-04 16:15:13 +08:00
今天 6s081 才刚看到这个,太巧了,刚好说到为什么不是 forkexec 而是 fork+exec,楼上已经解释得很清楚了
irytu
2021-04-04 16:58:58 +08:00
比如允许你进行 IO 重定向,去学学 6.828 或者 6.S081 吧
no1xsyzy
2021-04-04 17:16:18 +08:00
IIRC,还有一种用途,nginx 多个 worker 进程同时监听一个端口,用 fork 来共享 fd (打开的网络端口也是 fd )

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/767863

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX