- 论坛徽章:
- 0
|
本帖最后由 forward_ding 于 2012-06-26 10:35 编辑
问题一、
请教下:为send设置了不经历由系统缓冲区到socket缓冲区的拷贝,这跟不设置有什么不同(除了网络上说的性能提升外)?
数据经过系统缓冲区有什么好处?
问题二、
我现在程序有个问题:很容易出现EAGAIN(资源暂时不可用),程序用的是libevent封装的epoll,按照网上的说法有三种解决方法:
1.调大tcp_sendspace,使之大于send中的size参数。
但我觉得生产机参数一般不宜调吧,况且有多台;
2.在调用send前,在setsockopt函数中为SNDBUF设置更大的值。
这个倒是设置了,但是还是经常有EAGAIN出现;
3.使用write替代send,因为write没有设置O_NDELAY或者O_NONBLOCK
这个没有试,主要是考虑socket还是用send比较好,可以设置一些带外参数。
我也尝试在包裹函数中像处理EINTR中断一样处理EAGAIN,但后来发现过一段时间后程序cpu占用很严重,并且从日志观察到程序不处理数据了,像死循环。包裹函数如下:- /* Write "n" bytes to a descriptor. */
- int mysend(unsigned int fd, const void *vptr, int n)
- {
- errflag = 0;
- int nleft;
- int nwritten;
- const char *ptr;
- ptr = vptr;
- nleft = n;
- while (nleft > 0)
- {
- if ((nwritten = send(fd, ptr, nleft, 0)) <= 0)
- {
- errflag = 1;
- int errtmp = errno;
- if (errtmp == EINTR || errtmp == EAGAIN)
- nwritten = 0; /* and call write() again */
- else
- {
- LOG_ERROR(chatlog, "send message to fd %d error : %s", fd, strerror(errtmp));
- return(errtmp); /* error */
- }
- }
- nleft -= nwritten;
- ptr += nwritten;
- }
- return(n);
- }
复制代码 |
|