进程和线程的使用在前面博文已经讲述完毕,在完成一个最简单的服务器之后,就是要考虑下如何实现并发服务器了。
要实现服务的并发,只能通过进程和线程两种方式。
之前提到过listen_fd和connect_fd,listen用于监听是否有客户端连接,维护两个fd队列,没完成握手的和完成就绪的。
connect从就绪队列取描述符,这个connect_fd描述符将用于数据通信,所以要实现并发,就是将connect_fd分发到线程或进程上,由他们去独立完成通信。
在实际并发服务器应用场合,在IO层大多通过两个地方来提高代码效率,一个是描述符处理,一个是线程/进程调度处理。
下图简单描述了并发服务器的原理:
在处理IO时,会用到IO复用技术提高效率,在线程/进程分配时,会先构造线程池或进程池,并以某种方式调度,这些在后续博文详细描述。
下面是并发实现的简单代码,利用线程和进程实现服务器的并发。
进程实现:
1 /* File Name: server.c */ 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <unistd.h> 6 #include <sys/wait.h> 7 #include <errno.h> 8 #include <sys/types.h> 9 #include <sys/socket.h> 10 #include <sys/unistd.h> 11 #include <netinet/in.h> 12 13 const int DEFAULT_PORT = 2500; 14 const int BUFFSIZE = 1024; 15 const int MAXLINK = 10; 16 17 class sigOp 18 { 19 public: 20 void addSigProcess(int sig,void (*func)(int)); 21 void sendSig(const int sig, const int pid); 22 }; 23 24 void sigOp::addSigProcess(int sig,void (*func)(int)) 25 { 26 struct sigaction stuSig; 27 memset(&stuSig, '