这篇文章结合具体的使用示例来介绍一下exec中fork的使用区别。
使用fork vs 不使用fork
在前面的文章中,介绍了如下的使用示例用于演示回显的功能:
执行命令:socat -v tcp-l:8181 exec:"/bin/cat"
但是如果此命令稍作修改,加上fork,使用的时候区别在哪里呢?
执行命令:socat -v tcp-l:8181,fork exec:"/bin/cat"
不使用fork
执行命令:socat -v tcp-l:8182 exec:"/bin/cat"
执行之后,在另外的终端使用nc连接之后输入一行信息,可以看到回显
liumiaocn:~ liumiao$ nc localhost 8181
hello, liumiao
hello, liumiao
而socat所在终端的信息如下所示:
liumiaocn:~ liumiao$ socat -v tcp-l:8181 exec:"/bin/cat"
> 2020/03/01 10:37:24.579231 length=15 from=0 to=14
hello, liumiao
< 2020/03/01 10:37:24.579730 length=15 from=0 to=14
hello, liumiao
对socat的进程进行确认,可以看到就是一个正常的单进程
liumiaocn:~ liumiao$ ps -ef |grep socat |grep -v grep
501 27501 27202 0 10:37AM ttys003 0:00.00 socat -v tcp-l:8181 exec:/bin/cat
liumiaocn:~ liumiao$
此进程的父进程来源于bash,因为是在终端启动的。
liumiaocn:~ liumiao$ ps -ef |grep 27202 |grep -v grep
501 27202 27201 0 10:25AM ttys003 0:00.26 -bash
501 27501 27202 0 10:37AM ttys003 0:00.00 socat -v tcp-l:8181 exec:/bin/cat
liumiaocn:~ liumiao$
使用fork
执行命令:socat -v tcp-l:8182,fork exec:/bin/cat
这里换一个端口8182,执行之后,此时立即确认进程状态,可以看到和不使用fork一样都是单进程,父进程源于bash
liumiaocn:~ liumiao$ ps -ef |grep socat |grep -v grep
501 27519 27202 0 10:41AM ttys003 0:00.00 socat -v tcp-l:8182,fork exec:/bin/cat
liumiaocn:~ liumiao$ ps -ef |grep 27202 |grep -v grep
501 27202 27201 0 10:25AM ttys003 0:00.29 -bash
501 27519 27202 0 10:41AM ttys003 0:00.00 socat -v tcp-l:8182,fork exec:/bin/cat
liumiaocn:~ liumiao$
在另外的终端使用nc连接之后输入一行信息,可以看到回显
liumiaocn:~ liumiao$ nc localhost 8182
hi, greetings form one nc client
hi, greetings form one nc client
而socat所在终端的信息如下所示:
liumiaocn:~ liumiao$ socat -v tcp-l:8182,fork exec:"/bin/cat"
> 2020/03/01 10:45:08.164719 length=33 from=0 to=32
hi, greetings form one nc client
< 2020/03/01 10:45:08.165244 length=33 from=0 to=32
hi, greetings form one nc client
对socat的进程进行确认,可以看到区别了,针对nc新启动了一个进程进行回复
liumiaocn:~ liumiao$ ps -ef |grep socat |grep -v grep
501 27519 27202 0 10:41AM ttys003 0:00.00 socat -v tcp-l:8182,fork exec:/bin/cat
501 27527 27519 0 10:44AM ttys003 0:00.00 socat -v tcp-l:8182,fork exec:/bin/cat
liumiaocn:~ liumiao$
然后再次启动一个nc client进行连接并交互
liumiaocn:~ liumiao$ nc localhost 8182
this is another nc client of liumiao
this is another nc client of liumiao
可以看到socat所在终端的信息变化
liumiaocn:~ liumiao$ socat -v tcp-l:8182,fork exec:"/bin/cat"
> 2020/03/01 10:45:08.164719 length=33 from=0 to=32
hi, greetings form one nc client
< 2020/03/01 10:45:08.165244 length=33 from=0 to=32
hi, greetings form one nc client
> 2020/03/01 10:47:18.528873 length=37 from=0 to=36
this is another nc client of liumiao
< 2020/03/01 10:47:18.529407 length=37 from=0 to=36
this is another nc client of liumiao
最关键的是进程的情况,可以看到针对新的nc的客户端连接,socat的做法是新启一个进程与之通信
liumiaocn:~ liumiao$ ps -ef |grep socat |grep -v grep
501 27519 27202 0 10:41AM ttys003 0:00.00 socat -v tcp-l:8182,fork exec:/bin/cat
501 27527 27519 0 10:44AM ttys003 0:00.00 socat -v tcp-l:8182,fork exec:/bin/cat
501 27540 27519 0 10:47AM ttys003 0:00.00 socat -v tcp-l:8182,fork exec:/bin/cat
liumiaocn:~ liumiao$
总结
结合具体的示例,可以清楚地看到,fork的使用就是针对不同连接的客户端,会新生成新的进程与之对应