簡體   English   中英

C-發信號通知另一個線程進行清理並退出

[英]C - Signaling to another thread to cleanup and exit

我保證,這不是作業問題。

我正在編寫時間序列數據庫實現作為學習C的方法。

我已經編寫了一個客戶機/服務器對。 該服務器當前是偵聽端口上的套接字的回顯服務器。 客戶端連接到該端口並向其發送輸入行。 它使用readline獲取輸入, sendsend到客戶端套接字,從客戶端套接字recv一行,並將該行打印到終端。 沖洗,重復。 客戶端從recv獲得EOF時返回,此時客戶端知道連接已關閉。

問題是readline處於阻塞狀態,因此,如果服務器進程被殺死,即我對它進行了SIGINT處理,則客戶端仍在readline上處於阻塞狀態。 直到它send s,然后recv一個EOF之后,它才知道服務器已消失。

發生的事情是,如果recv上有EOF ,則客戶端會收到信號並立即退出。

我需要做的是創建3個pthreads -2個用於網絡客戶端( sendrecv ),1個用於終端。 終端調用readline和block。 它接受輸入,然后使用pthread_cond_t通知正在等待網絡客戶端send線程發送。 網絡客戶端recv線程一直在recv ,這將阻塞。 如果它是EOF ,它將引發SIGINTpthread_kill所有3個線程處理到該處理器, fprintf類似於“服務器關閉連接。”,然后調用exit (是的,我知道exit無論如何都會終止所有線程-這是一個練習清潔,看看我是否理解C)。

這是合適的方法嗎? 顯然,網絡客戶終端一直在這樣做。 什么是正確的方法?

如果我對您的理解正確,那么您希望在服務器退出后的readline (在write() / send()之前write()退出。 您的方法很好。 如果服務器已死,您將捕獲的唯一方法是,當您嘗試執行write() / send()您將獲得SIGPIPE ,它將在SIGPIPE其后導致退出。 因為默認情況下,除非有要發送或確認的數據,否則不會在連接上發送任何數據包。 因此,如果您只是在等待來自對等方的數據,則無法判斷對等方是否已經靜默離開,或者還沒有准備好發送或接收更多數據。 因此,您將需要在單獨的線程中為SIGPIPE一些輪詢器,並在獲取時退出。 您可以使用此readline功能來幫助您開始進行檢查。

/**
 * Simple utility function that reads a line from a file descriptor fd, 
 * up to maxlen bytes -- ripped from Unix Network Programming, Stevens.
 */
int
readline(int fd, char *buf, int maxlen)
{
    int n, rc;
    char c;

    for (n = 1; n < maxlen; n++) {
    if ((rc = read(fd, &c, 1)) == 1) {
        *buf++ = c;
        if (c == '\n')
        break;
    } else if (rc == 0) {
        if (n == 1)
        return 0; // EOF, no data read
        else
        break; // EOF, read some data
    } else
        return -1; // error
    }

    *buf = '\0'; // null-terminate
    return n;
}

這個問題已經回答過了。 我得到了史蒂文斯(Stevens)的幫助,第5章建議將readline調用與套接字read插入,以查找EOF 我在Google搜索libreadlineselect / poll ,結果如下:

用信號中斷c / c ++ readline

有一種使用交錯I / O的方法,因此libreadline不僅會阻塞:

http://www.delorie.com/gnu/docs/readline/rlman_41.html

感謝@ arayq2和@ G--建議史蒂文斯!

暫無
暫無

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

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