文章目录
一、多进程并发服务器
多进程并发服务器是一种经典的服务器架构,它通过创建多个子进程来处理客户端连接,从而实现并发处理多个客户端请求的能力。
使用原理
服务端:父进程创建主线程(负责链接),主线程在accept等待客户端连接,每来一个客户端进行通信,主线程都会通过fork函数创建一个处理线程与该客户端进行读取请求与回复响应。
难点
多进程并发服务器实现难点在于处理僵尸进程,我们采用再创建一个普通线程负责回收。
该线程继承自主线程。操作系统在处理进程退出后、发现僵尸进程时,向父进程发送SIGCHLED信号,通知回收。主线程需要屏蔽该信号(如果处理信号,会导致accept函数强制中断(EINTR))。普通线程会继承主线程的屏蔽字,然后进行捕捉设定,而后解除屏蔽,非阻塞循环回收。
特点
- 多进程模型有多个处理单元, 为多对多模型。
- 多进程模型中,子进程随客户端持续,链接成功创建,客户端退出则子进程退出。
- 僵尸进程如何回收 但是回收无论是阻塞回收还是非阻塞, 都会影响连接。
- 具备并发处理能力的服务器模型,可以并发连接并发处理,为若干客户端提供服务
- 并发量数量取决于进程数量
- 但频繁创建和销毁进程有庞大的系统开销
- 多进程稳定性强,因为每个处理单元是一个进程,一个进程异常退出不会影响其他进程
代码
只贴了主函数
cpp
/*#!/usr/bin/env c
# -*- coding: utf-8 -*-
# ************************************************************************
# *
# * @file:process_server.c
# * @author:WJQ
# * @date:2024-01-22 18:34
# * @version 1.0
# * @description: c Script
# * @Copyright (c) all right reserved
# *
#*************************************************************************
*/
#include <server.h>
int server_start(void)
{
int sockfd, csock;
struct sockaddr_in client_addr;
pid_t pid;
socklen_t addrlen;
sockfd = net_initializer();
printf("process tcp server runing..\n");
//设置屏蔽字
sigset_t set, oset;
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigprocmask(SIG_SETMASK, &set, &oset);
//回收线程创建
pthread_t tid;
int err;
if ((err = pthread_create(&tid, NULL, thread_wait, NULL)) > 0) {
printf("wait thread create error:%s\n", strerror(err));
exit(0);
}
while(SHUTDOWN) {
addrlen = sizeof(client_addr);
if ((csock = accept(sockfd, (struct sockaddr *)&client_addr, &addrlen)) > 0) {
pid = fork();
if (pid > 0) {
first_response(csock, client_addr);//父进程完成连接与首次响应
} else if (pid == 0) {
recv_request(csock);//子进程处理客户端请求
} else {
perror("accept call failed");
exit(0);
}
}
}
close(sockfd);
printf("server its done\n");
return 0;
}
二、多线程并发服务器
使用原理
其实跟多进程并发服务器非常类似。。。
但是少了处理僵尸进程问题,所以只用一个主线程(负责连接)就好。因为线程可以设置分离态。
难点
进程中sock可以通过继承的方式给子进程,线程就得参数传递。
特点
- 具备并发处理能力的服务器模型,可以并发连接并发处理,为若干客户端提供服务。
- 并发量数量取决于线程数量。
- 但频繁创建和销毁线程有庞大的系统开销。
- 稳定性较差,线程崩溃可能影响其他线程,但是开销小轻量级(线程安全问题)
总结
无论是多进程并发服务器还是多线程并发服务器,都有各自的缺点。常见的还是多路IO复用服务器。