簡體   English   中英

關閉套接字不釋放文件描述符

[英]close on socket not releasing file descriptor

在對我編寫的某些服務器代碼進行壓力測試時,我注意到即使我在描述符句柄上調用close()(並驗證錯誤的結果),也沒有釋放描述符,最終導致accept()返回錯誤“打開文件太多”。

現在我明白這是因為ulimit,我不明白為什么如果我在每個同步接受/讀/發送周期后調用close(),我會遇到它?

我通過運行帶有lsof的監視來驗證描述符實際上是在那里:

ctsvr  9733 mike 1017u  sock     0,7      0t0 3323579 can't identify protocol
ctsvr  9733 mike 1018u  sock     0,7      0t0 3323581 can't identify protocol
...

當然,大約有1000個左右。 此外,使用netstat檢查我可以看到沒有掛起的TCP狀態(沒有WAIT或STOPPED或任何東西)。

如果我只是從客戶端執行單個connect / send / recv,我會注意到套接字確實保留在lsof中; 所以這甚至不是負載問題。

服務器在Ubuntu Linux 64位計算機上運行。

有什么想法嗎?

因此,使用strace(感謝Gearoid),我不知道我是如何生活的,我注意到我實際上是在關閉描述符。

然而。 為了后代,我露出了愚蠢的錯誤:

Socket::Socket() : impl(new Impl) {
    impl->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    ....
}

Socket::ptr_t Socket::accept() {
    auto r = ::accept(impl->fd, NULL, NULL);
    ...
    ptr_t s(new Socket);
    s->impl->fd = r;
    return s;
}

正如您所看到的,我的構造函數立即分配了一個套接字,然后我用accept返回的描述符替換了描述符 - 創建了一個泄漏。 我已經將獨立的Acceptor類中的接受代碼重構為Socket類而不更改它。

使用strace我可以很容易地看到每次運行socket()導致我的燈泡時刻。

謝謝大家的幫助!

你有沒有在close()之后調用perror()? 我認為返回的字符串會給你一些幫助;

您最有可能掛在recv()send()命令上。 考慮使用setsockopt設置超時。

當套接字在另一端關閉時,我注意到lsof上有類似的輸出,但是我的線程在等待數據的recv()命令上保持套接字打開。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM