select服务器

                   多进程和多线程服务器有什么缺点呢?

多进程服务器缺点:

    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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值