我正在C中實現一個簡單的迭代TCP客戶端/服務器。服務器無限地在循環中列出。我們可以將參數傳遞給C中的信號嗎?
現在,如果在任何時間點出現Ctrl + c(SIGINT),我將如何釋放服務器中使用的資源?
例如,我在我自己的信號處理程序中捕獲到信號;我將如何獲取套接字描述符 和程序中使用的緩衝區以釋放它們?
我是socket編程的新手,任何建議,將不勝感激。
我正在C中實現一個簡單的迭代TCP客戶端/服務器。服務器無限地在循環中列出。我們可以將參數傳遞給C中的信號嗎?
現在,如果在任何時間點出現Ctrl + c(SIGINT),我將如何釋放服務器中使用的資源?
例如,我在我自己的信號處理程序中捕獲到信號;我將如何獲取套接字描述符 和程序中使用的緩衝區以釋放它們?
我是socket編程的新手,任何建議,將不勝感激。
請勿安裝信號處理程序。不要做任何事情。 SIGINT
的默認操作是終止進程,並且假設沒有其他進程爲您的套接字使用描述符,那麼當進程終止時,它們都將自然關閉並停止存在。
+1因爲我們都在一個不適用於他的問題的切線上。儘管他選擇了你的答案,你欠我一個。 :-p – 2011-03-14 05:43:35
我非常確定這一點,但是在標準中查找時仍然側目。 – 2011-03-14 05:50:47
@Brian:夠公平的。如果OP接受我的答案,請在答案上+1。 :-) – 2011-03-14 06:00:00
否。傳遞給您的信號處理程序的唯一參數是int
這是信號編號。
處理您描述的情況的典型方法是使用您的循環正在檢查的全局變量,例如int stopAndExit
。如果它被信號處理程序翻轉到1
您知道清理並退出。
編輯:欲瞭解更多詳情,請參閱下面的評論。
這樣做的一個問題是,如果您在信號到達時處於非重入函數。爲了解決這個問題,你實際上想延遲(阻塞)信號,然後在主循環中一個安全的地方處理它們。
最後編輯:除非您有一些外部操作需要清理之前,因此您保證以乾淨的狀態退出,這並不重要。無論如何,當你退出時,你的套接字描述符和緩衝區都會消失。沒有必要清理任何東西。
這個答案中的代碼是可怕的不安全的,調用各種UB,不應該在你的情況下使用。在信號處理程序中使用setjmp
/longjmp
僅作爲處理空指針取消引用的一種方式可以遠程工作,即使如此,爲了避免調用UB,它的範圍也需要極其有限。
這裏的處理清理的另一種可能的方式:
static jmp_buf buf;
static int ret = 0;
void handle(int sig)
{
ret = 1;
longjmp(buf, 1);
}
int func(void)
{
FILE *f = fopen(/* yadda */);
void (*orig)(int) = signal(SIGINT, handle);
if(setjmp(buf)) goto CLEANUP;
// use f
CLEANUP:
fclose(f);
signal(SIGINT, orig);
return ret;
}
當然,做了一大堆的拼搏,信號處理程序不能保證通過該標準的工作,但我敢肯定如果你擔心你不會嘗試處理信號。
這是另一個很好的解決方案,我真的很擔心釋放它們...... – Muse 2011-03-14 05:06:17
該解決方案調用非常危險的未定義行爲。 – 2011-03-14 05:34:13
爲了澄清,你的'fclose(f)'在一個'FILE'上運行,其狀態幾乎肯定不一致(IO期間信號中斷的最高概率時間)。這不僅僅是「標準不能保證」的工作。 – 2011-03-14 05:57:35
你剛開始使用全局變量!有時候,它們實際上是有用的,與許多人會想到的相反...... – 2011-03-14 04:42:00
@Carl:不,這只是一個信號處理程序是處理輸入的糟糕方法的標誌。 – 2011-03-14 05:20:11
@R ..或許這是一場半滿半場的爭吵? (順便說一下,我同意你們兩個的意見。) – 2011-03-14 05:21:32