2 回答

TA貢獻(xiàn)1806條經(jīng)驗(yàn) 獲得超8個(gè)贊
給recv() 設(shè)個(gè)timeout, 過(guò)了這個(gè)時(shí)間就返回超時(shí)的錯(cuò)誤,不要RECV一直阻塞在那里.
timeout 可以自己做一個(gè)。
下面是 google 弄得一段例子。
struct timeval tv; /* timeval and timeout stuff added by davekw7x */
int timeouts = 0;
tv.tv_sec = 3;
tv.tv_usec = 0;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv))
{
perror("setsockopt");
return -1;
}
if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof their_addr) == -1) {
perror("connect");
exit(1);
}
while (((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) && (++timeouts < 1000)) { /* loop to retry in case it timed out; added by davekw7x */
perror("recv");
printf("After timeout #%d, trying again:\n", timeouts);
}
printf("numbytes = %d\n", numbytes);
buf[numbytes] = '\0';
printf("Received: %s",buf);

TA貢獻(xiàn)1872條經(jīng)驗(yàn) 獲得超4個(gè)贊
建議你用strace看那幾個(gè)線程確切是卡在哪里
而且你描述的是,死循環(huán)。 recv函數(shù)怎么會(huì)死循環(huán)?
還有,當(dāng)你的系統(tǒng)壓力變大的時(shí)候, 會(huì)出現(xiàn)epoll提示某socket可用,但是等你去讀的時(shí)候該socket已經(jīng)被關(guān)閉的情況,你看看這種情況會(huì)不會(huì)對(duì)你的程序造成影響。
----------------------------
man recv
RETURN VALUE
These calls return the number of bytes received, or -1 if an error occurred. The return value will be 0 when the peer has performed an
orderly shutdown.
你可以看到,當(dāng)對(duì)端關(guān)閉socket的時(shí)候recv返回值是0。 那么作為你的程序,你又沒(méi)有判斷這種情況呢? 你默認(rèn)的如果是使用EPOLLET模式, 你肯定不停的讀socket直到EAGAIN出現(xiàn),但是如果返回值0的話,并不會(huì)出現(xiàn)EAGAIN。
建議你還是多用strace來(lái)查詢問(wèn)題所在,有時(shí)候比gdb更能直接找出原因。
、
還有再糾正一點(diǎn),recv是一個(gè)linux系統(tǒng)調(diào)用,要么是阻塞要么是返回,不存在死循環(huán)的問(wèn)題的, 死循環(huán)肯定是出在你的程序代碼中。 如果你覺(jué)得recv本身不退出又占用大量cpu,那就是linux庫(kù)出bug或者是內(nèi)核bug了。
添加回答
舉報(bào)