[英]C - Signaling to another thread to cleanup and exit
我保證,這不是作業問題。
我正在編寫時間序列數據庫實現作為學習C的方法。
我已經編寫了一個客戶機/服務器對。 該服務器當前是偵聽端口上的套接字的回顯服務器。 客戶端連接到該端口並向其發送輸入行。 它使用readline
獲取輸入, send
其send
到客戶端套接字,從客戶端套接字recv
一行,並將該行打印到終端。 沖洗,重復。 客戶端從recv
獲得EOF
時返回,此時客戶端知道連接已關閉。
問題是readline
處於阻塞狀態,因此,如果服務器進程被殺死,即我對它進行了SIGINT
處理,則客戶端仍在readline
上處於阻塞狀態。 直到它send
s,然后recv
一個EOF
之后,它才知道服務器已消失。
我想發生的事情是,如果recv
上有EOF
,則客戶端會收到信號並立即退出。
我想我需要做的是創建3個pthreads
-2個用於網絡客戶端( send
和recv
),1個用於終端。 終端調用readline
和block。 它接受輸入,然后使用pthread_cond_t
通知正在等待網絡客戶端send
線程發送。 網絡客戶端recv
線程一直在recv
,這將阻塞。 如果它是EOF
,它將引發SIGINT
, pthread_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搜索libreadline
並select
/ poll
,結果如下:
有一種使用交錯I / O的方法,因此libreadline
不僅會阻塞:
http://www.delorie.com/gnu/docs/readline/rlman_41.html
感謝@ arayq2和@ G--建議史蒂文斯!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.