1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > linux网络编程之socket:使用fork并发处理多个client的请求

linux网络编程之socket:使用fork并发处理多个client的请求

时间:2022-01-22 13:21:01

相关推荐

linux网络编程之socket:使用fork并发处理多个client的请求

在回射客户/服务器程序中,服务器只能处理一个客户端的请求,如何同时服务多个客户端呢?在未讲到select/poll/epoll等高级IO之前,比较老土的办法是使用fork来实现。网络服务器通常用fork来同时服务多个客户端,父进程专门负责监听端口,每次accept一个新的客户端连接就fork出一个子进程专门服务这个客户端。但是子进程退出时会产生僵尸进程,父进程要注意处理SIGCHLD信号和调用wait清理僵尸进程,最简单的办法就是直接忽略SIGCHLD信号。

上述程序利用了一点,就是父子进程共享打开的文件描述符,因为在子进程已经用不到监听描述符,故将其关闭,而连接描述符对父进程也没价值,将其关闭。当某个客户端关闭,则read 返回0,退出循环,子进程顺便exit,但如果没有设置对SIGCHLD信号的忽略,则因为父进程还没退出,故子进程会变成僵尸进程。

现在先运行server,再打开另外两个终端,运行client(直接用回射客户/服务器程序中的客户端程序),可以看到server输出如下:

simba@ubuntu:~/Documents/code/linux_programming/UNP/socket$ ./echoser_fork

recv connect ip=127.0.0.1 port=46452

recv connect ip=127.0.0.1 port=46453

在另一个终端ps一下:

simba@ubuntu:~$ ps aux | grep echoser

simba 3300 0.0 0.0 280 pts/0 S+ 22:10 0:00 ./echoser_fork

simba 3303 0.0 0.0 60 pts/0 S+ 22:10 0:00 ./echoser_fork

simba 3305 0.0 0.0 60 pts/0 S+ 22:10 0:00 ./echoser_fork

simba 3313 0.0 0.0 4392 836 pts/3 S+ 22:12 0:00 grep --color=auto echoser

simba@ubuntu:~$

发现共有3个进程,其中一个是父进程处于监听中,另外两个是子进程处于对客户端服务中,现在ctrl+c 掉其中一个client,由上面的分析可知对应服务的子进程也会退出,而因为我们设置了父进程对SIGCHLD信号进行忽略,故不会产生僵尸进程,输出如下:

simba@ubuntu:~$ ps aux | grep echoser

simba 3300 0.0 0.0 280 pts/0 S+ 22:10 0:00 ./echoser_fork

simba 3305 0.0 0.0 60 pts/0 S+ 22:10 0:00 ./echoser_fork

simba 3321 0.0 0.0 4392 836 pts/3 S+ 22:13 0:00 grep --color=auto echoser

如果把29行代码注释掉,上述的情景输出可能为:

simba@ubuntu:~$ ps aux | grep echoser

simba 3125 0.0 0.0 280 pts/0 S+ 21:38 0:00 ./echoser_fork

simba 3128 0.0 0.0 0 0 pts/0 Z+ 21:38 0:00 [echoser_fork] <defunct>

simba 3130 0.0 0.0 60 pts/0 S+ 21:38 0:00 ./echoser_fork

simba 3141 0.0 0.0 4392 832 pts/3 S+ 21:40 0:00 grep --color=auto echoser

即子进程退出后变成了僵尸进程。

如果不想忽略SIGCHLD信号,则必须在信号处理函数中调用wait处理,但这里需要注意的是wait只能等待第一个退出的子进程,所以这里需要使用waitpid函数,如下所示:

实际上使用 while (wait(NULL) > 0) ; 也可以达到同样的效果。

来源:csdn 作者:Simba888888

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。