笔者在学习unix网络编程时,第一个回显程序,服务器使用的是先accept一个链接,然后fork一个子进程,父进程关闭链接socket,继续使用监听socket,而子进程关闭监听socket,使用链接socket。
在学习select后,笔者改造原先代码的时候,先select到监听套接字,然后将链接套接字加入到fd_set里面继续select,当链接socket中有数据到达的时候,select告诉有数据,此时调用fork()产生一个子进程,在子进程中处理数据,而且不能在父进程中关闭链接套接字,因为select还需要使用,如果关闭了,程序异常。然而,此时程序并没有正常运行,回显数据是成功了,但是服务器端出现了很多子进程,这是什么原因呢? 笔者研究后发现,在子进程读取数据的同时,父进程开始了新一轮的select,如果父进程select的速度比子进程read数据的速度要快,所以此时父进程select仍发现原来的套接字上有数据,又一次调用了fork产生了子进程,在子进程read数据结束之前,父进程select了多次,并调用了fork多次,所以产生了多个子进程。
所以,得出结论,用select的同时,再次调用fork,无法保证顺序问题,其实select自身就可以完成多个客户端并发连接请求了。
可以把fork,select看做是实现网络并发程序的两种方式。
阅读(628) | 评论(0) | 转发(0) |