高并发服务器
高并发服务器框架
网上看到这张图不错,就拿过来了。
多进程并发服务器
- 父进程监听,子进程领任务做具体逻辑的实现。
- 父进程关闭
cfd
,close(cfd)
,子进程关闭lfd
,close(lfd)
,因为父子进程共享文件描述符表。 - 子进程回收机制,通过信号捕捉函数
while(1){waitpid()...}
- 捕捉的信号
SIGCHLD()
- 进程死亡只能由父进程回收
使用多进程并发服务器时要考虑以下几点:
- 父进程最大文件描述个数(父进程中需要
close
关闭accept
返回的新文件描述符) - 系统内创建进程个数(与内存大小相关)
- 进程创建过多是否降低整体服务性能(进程调度)
/* server.c */
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "wrap.h"
#define MAXLINE 80
#define SERV_PORT 8080
#define SERVER_IP 127.0.0.1
void do_sigchild(int num)
{
while (waitpid(0, NULL, WNOHANG) > 0);
}
int main(void)
{
struct sockaddr_in servaddr, cliaddr;
socklen_t cliaddr_len;
int listenfd, connfd;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
int i, n;
pid_t pid;
struct sigaction newact;
newact.sa_handler = do_sigchild;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
sigaction(SIGCHLD, &newact, NULL);
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
Listen(listenfd, 20);
printf("Accepting connections ...\n");
while (1) {
cliaddr_len = sizeof(cliaddr