2016-09-23 48 views
6

當我們的UNIX/C程序需要緊急出口時,我們使用exit(3)函數並安裝atexit(3)處理程序進行應急清理。這種方法運行良好,直到我們的應用程序被線程化,此時atexit()處理程序停止工作,可以預測。POSIX標準對atexit()處理程序中線程堆棧的說明是什麼?什麼是操作系統的做法?

我們瞭解到通過試驗,線程可能已經死在的atexit()處理錯誤,和他們的籌碼釋放。

我沒有在標準鏈接線程中找到一個引用使用atexit()函數消失:線程在從main()返回後不再存在,但是在調用atexit()之後還是之後? Linux,FreeBSD和Mac上的實際操作是什麼?

有沒有在多線程程序的良好格局緊急清理?

回答

3

POSIX標準這似乎

並沒有被Posix的定義atexit處理器是否被稱爲線程被終止exit之前或之後。

有兩個(或三個)方式的進程終止「正常」。

  • 所有線程都終止。當最後一個線程退出時,無論是通過返回還是呼叫pthread_exit,都會運行atexit處理程序。在這種情況下,沒有其他線程。 (這取決於平臺,如果主線程終止而不是exit,其他平臺可能終止其他線程,其他平臺則不會)。

  • 一個線程調用exit。在這種情況下,將會運行atexit處理程序並終止所有線程。 Posix沒有按照什麼順序指定。

  • main回報。這或多或少地相當於調用exit()作爲main的最後一行,因此可以如上處理。

OS實踐

在Linux中,文件https://linux.die.net/man/2/exit 說線程由_exit調用exit_group終止,並_exit之後atexit處理程序調用。因此,在調用exit的Linux中,任何atexit處理程序都在線程終止之前運行。請注意,它們在調用exit的線程上運行,而不是調用atexit的線程。

在Windows上,如果你在意的話,行爲是一樣的。

模式進行緊急清理。

最好的模式是:永遠不要處於需要緊急清理的狀態。

  • 沒有保證您的清理將運行因爲 你可以有一個kill -9或 停電。
  • 因此,您需要能夠在該方案中恢復。
  • 如果您可以從中恢復,您還可以從abort中恢復,因此您可以使用abort作爲您的緊急出口。

如果你不能做到這一點,或者如果你有「最好有」的你想要做清理,atexit處理要細提供你先緩慢停止所有線程的過程中,以防止在進行清理時進入不一致的狀態。

+0

我認爲這個用例應該注意POSIX/ISO委員會的討論。也就是說,我同意你永遠不希望進入一個你需要清理的狀態,但是我已經在一個或兩個地方找到了自己 - 最近如果我的TAP符合單元/迴歸測試代碼引發異常,然後我得到不是消息輸出,或者我必須處理atexit。在多線程的情況下沒有嚴格的atexit定義可能會有問題。 – EBo

相關問題