亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

有誰碰到過類似問題么?或者是能指導一個努力的方向?

有誰碰到過類似問題么?或者是能指導一個努力的方向?

德瑪西亞99 2023-03-19 21:17:32
linux服務器,在連接只有1000個時候,一切正常,到連接到2000以上的時候,就死循環在recv函數里面,cpu占用率很高,因為recv是系統函數,也不知道他在里面干什么。程序是epoll實現的。不是建立連接的時候死循環,而是跑了一段時間后,在調用recv函數的時候。我這里是服務器,接受連接, 是一個進程多個線程。每個線程管理多個連接。每個線程使用epoll方式響應網絡事件,當網絡可讀的時候,就去調用recv函數讀取數據。在進行測試的時候,發現1000個連接是好了,如果是3000個連接,跑一個晚上后,就有好幾個線程死循環在系統的recv函數了。 
查看完整描述

2 回答

?
慕森卡

TA貢獻1806條經驗 獲得超8個贊

給recv() 設個timeout, 過了這個時間就返回超時的錯誤,不要RECV一直阻塞在那里.

timeout 可以自己做一個。

下面是 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);

 


查看完整回答
反對 回復 2023-03-22
?
守著一只汪

TA貢獻1872條經驗 獲得超4個贊

建議你用strace看那幾個線程確切是卡在哪里

而且你描述的是,死循環。 recv函數怎么會死循環?

還有,當你的系統壓力變大的時候, 會出現epoll提示某socket可用,但是等你去讀的時候該socket已經被關閉的情況,你看看這種情況會不會對你的程序造成影響。 
----------------------------
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.

你可以看到,當對端關閉socket的時候recv返回值是0。 那么作為你的程序,你又沒有判斷這種情況呢? 你默認的如果是使用EPOLLET模式, 你肯定不停的讀socket直到EAGAIN出現,但是如果返回值0的話,并不會出現EAGAIN。

建議你還是多用strace來查詢問題所在,有時候比gdb更能直接找出原因。

還有再糾正一點,recv是一個linux系統調用,要么是阻塞要么是返回,不存在死循環的問題的, 死循環肯定是出在你的程序代碼中。 如果你覺得recv本身不退出又占用大量cpu,那就是linux庫出bug或者是內核bug了。


查看完整回答
反對 回復 2023-03-22
  • 2 回答
  • 0 關注
  • 112 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號