2011-03-14 202 views
0

我正在C中實現一個簡單的迭代TCP客戶端/服務器。服務器無限地在循環中列出。我們可以將參數傳遞給C中的信號嗎?

現在,如果在任何時間點出現Ctrl + c(SIGINT),我將如何釋放服務器中使用的資源?

例如,我在我自己的信號處理程序中捕獲到信號;我將如何獲取套接字描述符 和程序中使用的緩衝區以釋放它們?

我是socket編程的新手,任何建議,將不勝感激。

+2

你剛開始使用全局變量!有時候,它們實際上是有用的,與許多人會想到的相反...... – 2011-03-14 04:42:00

+0

@Carl:不,這只是一個信號處理程序是處理輸入的糟糕方法的標誌。 – 2011-03-14 05:20:11

+0

@R ..或許這是一場半滿半場的爭吵? (順便說一下,我同意你們兩個的意見。) – 2011-03-14 05:21:32

回答

2

請勿安裝信號處理程序。不要做任何事情。 SIGINT的默認操作是終止進程,並且假設沒有其他進程爲您的套接字使用描述符,那麼當進程終止時,它們都將自然關閉並停止存在。

+1

+1因爲我們都在一個不適用於他的問題的切線上。儘管他選擇了你的答案,你欠我一個。 :-p – 2011-03-14 05:43:35

+0

我非常確定這一點,但是在標準中查找時仍然側目。 – 2011-03-14 05:50:47

+0

@Brian:夠公平的。如果OP接受我的答案,請在答案上+1。 :-) – 2011-03-14 06:00:00

2

否。傳遞給您的信號處理程序的唯一參數是int這是信號編號。

處理您描述的情況的典型方法是使用您的循環正在檢查的全局變量,例如int stopAndExit。如果它被信號處理程序翻轉到1您知道清理並退出。

編輯:欲瞭解更多詳情,請參閱下面的評論。

這樣做的一個問題是,如果您在信號到達時處於非重入函數。爲了解決這個問題,你實際上想延遲(阻塞)信號,然後在主循環中一個安全的地方處理它們。

最後編輯:除非您有一些外部操作需要清理之前,因此您保證以乾淨的狀態退出,這並不重要。無論如何,當你退出時,你的套接字描述符和緩衝區都會消失。沒有必要清理任何東西。

+0

所以我也需要使套接字描述符全局釋放他們..... – Muse 2011-03-14 04:44:41

+0

嗯,不。所有這些都可用於您的主服務器環路。每次循環時只需檢查'stopAndExit'全局。當它看到它應該停止並退出時,它會清理乾淨,然後退出。 – 2011-03-14 04:47:27

+0

@Brian:所以我認爲這是做它的唯一方法....... – Muse 2011-03-14 04:52:21

0

這個答案中的代碼是可怕的不安全的,調用各種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; 
} 

當然,做了一大堆的拼搏,信號處理程序不能保證通過該標準的工作,但我敢肯定如果你擔心你不會嘗試處理信號。

+0

這是另一個很好的解決方案,我真的很擔心釋放它們...... – Muse 2011-03-14 05:06:17

+0

該解決方案調用非常危險的未定義行爲。 – 2011-03-14 05:34:13

+1

爲了澄清,你的'fclose(f)'在一個'FILE'上運行,其狀態幾乎肯定不一致(IO期間信號中斷的最高概率時間)。這不僅僅是「標準不能保證」的工作。 – 2011-03-14 05:57:35

相關問題