select服务器
来源:互联网 发布:在重庆网络教育有哪些 编辑:程序博客网 时间:2024/06/08 18:29
多进程和多线程服务器有什么缺点呢?
多进程服务器缺点:
1.内存消耗比较大,每个进程都独立加载完整的应用环境
2.cpu消耗偏高,高并发下,进程之间频繁进行上下文切换,需要大量的内存换页操作
3.很低的io并发处理能力,只适合处理短请求,不适合处理长请求
多线程服务器缺点:
1.不方便操作系统的管理
2.VM对内存的管理要求非常高,GC的策略会影响多线程并发能力和系统吞吐量
3.由于存在对共享资源操作,一旦出现线程"死锁"和线程阻塞,很容易使整个应用失去可用性
用他们编写的服务器,当用户增多时,服务器性能也会下降。
为了解决这个问题,select就出现了。
select服务器的优点:
1.高性能(与多进程和多线程比较)
(1)select一次等待多个文件描述符;
(2)select的cpu压力低;
(3)等待时间变短,提升了性能;
select服务器的缺点:
(1)每次调⽤用select,都需要把fd集合从⽤用户态拷贝到内核态,这个开销在fd很多时会很⼤大
(2)同时每次调⽤用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很⼤大
(3)select⽀支持的⽂文件描述符数量太⼩小了,默认是1024
select服务器代码如下
#include#include #include #include #include #include #include int array_fds[1024];int startup(char * _ip, int _port){int sock = socket(AF_INET, SOCK_STREAM, 0);if(sock < 0){perror("create socket is fail");return 2;}struct sockaddr_in peer;peer.sin_family = AF_INET;peer.sin_port = htons(_port);peer.sin_addr.s_addr = inet_addr(_ip);int opt = 1;setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));if(bind(sock, (struct sockaddr*)&peer, sizeof(peer)) < 0){perror("bind");return 3;}if(listen(sock, 10) < 0){perror("listen");return 4;}return sock;}static void Usage(const char* proc){printf("%s[ip][port]\n", proc);}int main(int argc, char *argv[]){if(argc != 3){Usage(argv[0]);return 1;}int listensock = startup(argv[1], atoi(argv[2]));int maxfd = 0;int array_size = sizeof(array_fds)/sizeof(array_fds[0]);fd_set rfds;array_fds[0] = listensock;int i = 1;for(; i < array_size; i++){array_fds[i] = -1;}while(1){struct timeval _timeout = {5, 0};FD_ZERO(&rfds);maxfd = -1;for(i = 0; i < array_size; i++){if(array_fds[i] > 0){FD_SET(array_fds[i], &rfds);if(array_fds[i] > maxfd){maxfd = array_fds[i];}}}switch(select(maxfd + 1, &rfds, NULL, NULL, &_timeout)){case 0:printf("timeout....");break;case -1:perror("select");break;default:{int j = 0;for(; j < array_size; j++){if(array_fds[j] < 0)continue; if(j == 0 && FD_ISSET(array_fds[j], &rfds)){struct sockaddr_in client;socklen_t len = sizeof(client);int new_fd = accept(array_fds[j], (struct sockaddr*)&client, &len);if(new_fd < 0){perror("new_fd:accept");continue;}else{//printf("get a new client:(%s:%d)");int k = 1;for(; k < array_size; k++){if(array_fds[k] < 0){array_fds[k] = new_fd;break;}}if(k == array_size){close(new_fd);}}}else if(j != 0 && FD_ISSET(array_fds[j], &rfds)){char buf[1024];ssize_t s = read(array_fds[j], buf, sizeof(buf)-1);if(s > 0){buf[s] = 0;printf("client say# %s\n", buf);}else if(s == 0){printf("client is quit!");close(array_fds[j]);array_fds[j] = -1;}else{perror("read");close(array_fds);array_fds[j] = -1;}}}}break;}}return 0;}
阅读全文
0 0
- Select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- Select服务器
- select服务器
- select多路单线程服务器
- select模型服务器代码
- python 服务器 select 游戏
- tcp服务器(使用select)
- 45、扑克牌顺子
- 创建信号量RACSignal
- python3 二叉树及单链表
- github简单使用教程
- SET NOCOUNT ON 作用
- select服务器
- jni string 转换
- 前端工程师新手必读
- VIM常用命令
- Netty简单示例----客户端与服务器通信
- [golang note] 错误处理
- vi常用命令
- mybatis <trim>标签
- TSLint: Identifier 'errMsg' is never reassigned; use 'const' instead of 'let'. (prefer-const)