社区
Linux/Unix社区
帖子详情
(请高手救命啊!在线等)Socket Send的时候,不停的得到EINTR错误返回, 请问是为什么?
kkong2000
2003-08-19 09:58:51
在Redhat7.3下,多线程多CPU,在非常高频率Socket端口Send操作的时候,大概是1000次/秒以上, 持续出现EINTR错误。 有高手知道原因,或者知道怎么解决,或者知道相关网上信息的,请帮忙告知。分数不是问题!
先谢谢了!
...全文
594
26
打赏
收藏
(请高手救命啊!在线等)Socket Send的时候,不停的得到EINTR错误返回, 请问是为什么?
在Redhat7.3下,多线程多CPU,在非常高频率Socket端口Send操作的时候,大概是1000次/秒以上, 持续出现EINTR错误。 有高手知道原因,或者知道怎么解决,或者知道相关网上信息的,请帮忙告知。分数不是问题! 先谢谢了!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
26 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
westar
2003-08-21
打赏
举报
回复
up
fierygnu
2003-08-21
打赏
举报
回复
看了一下你的代码,
if (send_ret < 0)
{
if (errno==EPIPE)
{
(writer->FDS)->shutdown(sciNode->fd);
scoNode = new SCMQNode;
scoNode->fd = sciNode->fd;
scoNode->Action = CLOSEFD_RECV;
scoNode->len = 0;
scoNode->msg = NULL;
(writer->SCIMsgQueue)->put(scoNode);
}
if (errno==EINTR) //这里应该用else if
{
sendIntrFlag = true;
continue;
}
}
如果EPIPE处理分支里的代码产生一个错误,此错误会设置errno,如果是EINTR就会进入EINTR的处理分支。改成else if试试。
fierygnu
2003-08-21
打赏
举报
回复
楼主结贴了,能不能明示一下到底是什么问题,我们也学习学习啊。
fierygnu
2003-08-20
打赏
举报
回复
strace报告有什么问题吗?
kkong2000
2003-08-20
打赏
举报
回复
还是没有实质性的进展,有高手有类似的经历吗?请赐教经验啊!
kkong2000
2003-08-20
打赏
举报
回复
可是我程序里面除了启动时,用来成为daemon进程时,调用了2次fork,其他没有fork的调用了。我猜测是不是,在一定条件下rt_sigsuspend的返回值EINTR,覆盖了EBADF?
fierygnu
2003-08-20
打赏
举报
回复
In a multithreaded application, EINTR may be returned whenever another thread or LWP calls fork(2).
我想你的问题就出现在这里。限制fork数目试试。
kkong2000
2003-08-20
打赏
举报
回复
strace报告发现应该返回EBADF的情况下,返回了EINTR的错误。 我的程序中对于EBADF的错误处理是丢弃这个数据。
正常返回errno = 32的时候的strace:
******************************************************************************
kill(19890, SIGRTMIN) = 0
send(430, "\217\1\0\10\27\374@3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 128, 0x4000) = -1 EPIPE (Broken pipe)
rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0
rt_sigsuspend([] <unfinished ...>
--- SIGRTMIN (Real-time signal 0) ---
<... rt_sigsuspend resumed> ) = -1 EINTR (Interrupted system call)
sigreturn() = ? (mask now [RTMIN])
*******************************************************************************
错误返回Errno = 4的时候的strace:
*******************************************************************************
kill(19720, SIGRTMIN) = 0
send(82, "\217\1\0\10\27\374@3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 128, 0x4000) = -1 EBADF (Bad file descriptor)
rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0
rt_sigsuspend([] <unfinished ...>
--- SIGRTMIN (Real-time signal 0) ---
<... rt_sigsuspend resumed> ) = -1 EINTR (Interrupted system call)
sigreturn() = ? (mask now [RTMIN])
******************************************************************************
wwwunix
2003-08-19
打赏
举报
回复
另外,你还可以注册一个信号处理函数,看看是什么信号中断了你的系统调用.
wwwunix
2003-08-19
打赏
举报
回复
出现EINTR的原因是进程执行了一个低速系统调用而阻塞期间捕捉到一个信号,则该系统调用就被中断不再继续执行.
建议:当你接受到EINTR后,重发刚才数据.或者将你不用的信号屏蔽掉.
fierygnu
2003-08-19
打赏
举报
回复
你的程序里使用信号了吗?
kkong2000
2003-08-19
打赏
举报
回复
没有较好的排版,请海涵。 另:发送是Block模式的。
void* SCMsgWriter::thread_func(void* data)
{
SCMsgWriter* writer = *(SCMsgWriter**)data;
int send_ret=0;
bool sendIntrFlag = false;
struct SCMQNode* sciNode=NULL;
struct SCMQNode* scoNode=NULL;
try
{
while(1)
{
if (sendIntrFlag == false)
{
sciNode = writer->SCOMsgQueue->get();
if (sciNode == NULL) continue;
}
else
{
sendIntrFlag = false;
}
if (sciNode->Action == MESSAGE_SEND)
{
send_ret = 0;
send_ret = send(sciNode->fd, sciNode->msg, sciNode->len, MSG_NOSIGNAL);
if (send_ret < 0)
{
if (errno==EPIPE)
{
(writer->FDS)->shutdown(sciNode->fd);
scoNode = new SCMQNode;
scoNode->fd = sciNode->fd;
scoNode->Action = CLOSEFD_RECV;
scoNode->len = 0;
scoNode->msg = NULL;
(writer->SCIMsgQueue)->put(scoNode);
}
if (errno==EINTR)
{
sendIntrFlag = true;
continue;
}
}
else if (send_ret>=0 && send_ret<sciNode->len )
{
(writer->FDS)->shutdown(sciNode->fd);
scoNode = new SCMQNode;
scoNode->fd = sciNode->fd;
scoNode->Action = CLOSEFD_RECV;
scoNode->len = 0;
scoNode->msg = NULL;
(writer->SCIMsgQueue)->put(scoNode);
}
}
else if ((sciNode->Action==CLOSEFD_SEND) || (sciNode->Action==CHECK_VERSION))
{
send_ret = 0;
send_ret = send(sciNode->fd, sciNode->msg, sciNode->len, MSG_NOSIGNAL);
if (send_ret < 0)
{
if (errno==EINTR)
{
continue;
}
}
writer->FDS->shutdown(sciNode->fd);
}
delete [] sciNode->msg;
delete sciNode;
sciNode = NULL;
}
}
catch(...)
{
TRACE("SCMsgWriter Exception Exit!", LEVEL_CRITICAL);
}
TRACE("SCMsgWriter Return!", LEVEL_CRITICAL);
return NULL;
}
kkong2000
2003-08-19
打赏
举报
回复
没有较好的排版,请海涵。 另:发送是Block模式的。
void* SCMsgWriter::thread_func(void* data)
{
SCMsgWriter* writer = *(SCMsgWriter**)data;
int send_ret=0;
bool sendIntrFlag = false;
struct SCMQNode* sciNode=NULL;
struct SCMQNode* scoNode=NULL;
try
{
while(1)
{
if (sendIntrFlag == false)
{
sciNode = writer->SCOMsgQueue->get();
if (sciNode == NULL) continue;
}
else
{
sendIntrFlag = false;
}
if (sciNode->Action == MESSAGE_SEND)
{
send_ret = 0;
send_ret = send(sciNode->fd, sciNode->msg, sciNode->len, MSG_NOSIGNAL);
if (send_ret < 0)
{
if (errno==EPIPE)
{
TRACEX_LOCK;
TRACEX_UNLOCK;
(writer->FDS)->shutdown(sciNode->fd);
scoNode = new SCMQNode;
scoNode->fd = sciNode->fd;
scoNode->Action = CLOSEFD_RECV;
scoNode->len = 0;
scoNode->msg = NULL;
(writer->SCIMsgQueue)->put(scoNode);
}
if (errno==EINTR)
{
sendIntrFlag = true;
continue;
}
}
else if (send_ret>=0 && send_ret<sciNode->len )
{
(writer->FDS)->shutdown(sciNode->fd);
scoNode = new SCMQNode;
scoNode->fd = sciNode->fd;
scoNode->Action = CLOSEFD_RECV;
scoNode->len = 0;
scoNode->msg = NULL;
(writer->SCIMsgQueue)->put(scoNode);
}
}
else if ((sciNode->Action==CLOSEFD_SEND) || (sciNode->Action==CHECK_VERSION))
{
send_ret = 0;
send_ret = send(sciNode->fd, sciNode->msg, sciNode->len, MSG_NOSIGNAL);
if (send_ret < 0)
{
TRACEX_LOCK;
TRACEX(LEVEL_MINOR)<<"send error! errno is "<<errno<<endl;
TRACEX_UNLOCK;
if (errno==EINTR)
{
continue;
}
}
writer->FDS->shutdown(sciNode->fd);
}
delete [] sciNode->msg;
delete sciNode;
sciNode = NULL;
}
}
catch(...)
{
TRACE("SCMsgWriter Exception Exit!", LEVEL_CRITICAL);
}
TRACE("SCMsgWriter Return!", LEVEL_CRITICAL);
return NULL;
}
tomascat
2003-08-19
打赏
举报
回复
看看发送的字节和头计数是否相符!
wwwunix
2003-08-19
打赏
举报
回复
能否将你出错部分的代码帖上来?
kkong2000
2003-08-19
打赏
举报
回复
不是的,我在发送数据的时候,发生EINTR错误的!
(感谢你的关注)
wwwunix
2003-08-19
打赏
举报
回复
你是不是在调用select()时出现的EINTR错误?
kkong2000
2003-08-19
打赏
举报
回复
帮忙顶的,一定有分相报,谢谢啦!
kkong2000
2003-08-19
打赏
举报
回复
我比较菜,还不会用strace,看来要研究一下。
fierygnu
2003-08-19
打赏
举报
回复
用strace跟踪你的应用,看看发生EINTR时是怎么回事?
加载更多回复(6)
socket
编程中的
EINTR
是什么?
socket
编程中的
EINTR
是什么?
socket
send
返回
值_Linux网络编程中
socket
常见
错误
分析
socket
错误
码:
EINTR
: 4阻塞的操作被取消阻塞的调用打断。如设置了发送接收超时,就会遇到这种
错误
。只能针对阻塞模式的
socket
。读,写阻塞的
socket
时,-1
返回
,
错误
号为INTR。另外,如果出现
EINTR
即errno为4,
错误
...
Linux -
socket
编程处理
EINTR
错误
Linux -
socket
编程处理
EINTR
...在linux的
socket
编程中,经常要处理
EINTR
错误
,其值为4,用strerror(errno)调用
返回
的
错误
描述为:Interrupted system call. 这里给出一个connect连接中对
EINTR
处理的网址: http://
Socket
通信——Linux下,errno=
EINTR
的
错误
处理
2.没有数据,则进入睡眠模式,当超时、数据到达、发生
错误
则唤醒进程处理 采用睡眠来等待,发生信号的时候进程会被唤醒,
socket
接口唤醒后检查有无未处理的信号(signal_pending)会
返回
EINTR
错误
。 处理方式,无需...
linux
socket
错误
处理,Linux -
socket
编程处理
EINTR
错误
在linux的
socket
编程中,经常要处理
EINTR
错误
,其值为4,用strerror(errno)调用
返回
的
错误
描述为:Interruptedsystem call. 这里给出一个connect连接中对
EINTR
处理的网址:另外转载网络上其他兄弟对
EINTR
错误
的处理...
Linux/Unix社区
23,125
社区成员
74,509
社区内容
发帖
与我相关
我的任务
Linux/Unix社区
Linux/Unix社区 应用程序开发区
复制链接
扫一扫
分享
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章