七叶笔记 » golang编程 » linux fork多进程并发服务器模型之C/C++代码实战

linux fork多进程并发服务器模型之C/C++代码实战

今天我们一起来聊聊多进程实现与多个客户端进行通信。

如果是在while中循环accept, 然后循环处理事情, 此时, 这种服务是迭代服务, 只能逐一处理客户端的请求, 后一个请求必须等前一个请求处理完毕, 无法并发处理, 真是急死人。 要实现并发, 我们可以考虑多线程, 也可以考虑多进程, 本文来说说后者。 在我们的多进程服务器模型中, 我们用父进程来处理连接(监听 socket ), 用fork子进程的方法来处理通信(通信socket), 各司其职, 美哉。

一旦涉及到fork, 就必须注意僵尸进程的处理, 所以, 我们要用waitpid进行收尸, 这一点, 我们已经说过了。 另外, 要注意, 父子进程共享socket句柄的文件表(如果不理解的话, 建议看看APUE), 所以close socket的时候, 只是使引用计数减1, 并不是真正地直接关闭socket(减为0才是真正的关闭)。

废话少说, 直接上菜。

服务端程序为:

启动它。

客户端程序为:

我们开启一个客户端, 此时如下:

客户端信息为:

服务端信息为:

可以看到, 服务端16402子进程是与客户端通信的进程, 父进程16096是监听的父进程(主进程)。

另外再开启一个客户端(不要关闭旧的客户端), 此时如下:

新客户端信息为:

服务端信息为:

可以看到, 父进程16096新开了一个子进程16497来与新的客户端进行通信。

我们关闭第一个客户端, 然后看到服务端为:

我们再关闭第二个客户端, 然后看到服务端为:

显然, 客户端退出后, 发FIN包, 服务端子进程的recv函数就为0, 退出子进程的while循环了, 因此, 对应的子进程就over了, 而且不会留下僵尸进程(有waitpid)。 而且, 我们可以看到, 负责连接管理(accept)的父进程(主进程)依然安然无恙, 优哉游哉地等待下一个客户端连接。

在这里, 我们可以看到, 这个服务器是并发的, 而不是迭代的。 什么意思呢? 你看, 即使子进程处理业务需要很久很久, 那么上述服务依然能并发地响应n个几乎同时到达的客户端, 此时,父进程开启n个子进程, 并发地工作, 并发地与客户端进行通信, 而且还互不干扰, 大大提升了服务满意度。

注:需要C/C++ Linux服务器开发学习资料私信“资料”(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

相关文章