進(jìn)程捕捉到信號(hào)并對(duì)其進(jìn)行處理時(shí),進(jìn)程正在執(zhí)行的指令序列就被信號(hào)處理程序臨時(shí)中斷,它首先執(zhí)行該信號(hào)處理程序中的指令。如果從信號(hào)處理程序返回(例如信號(hào)處理程序沒(méi)有調(diào)用exit或longjmp),則繼續(xù)執(zhí)行在捕捉到信號(hào)時(shí)進(jìn)程正在執(zhí)行的正常指令序列。但在信號(hào)處理程序中,不能判斷捕捉到信號(hào)時(shí)進(jìn)程在何處執(zhí)行。如果程序正在執(zhí)行malloc,在其堆中分配另外的存儲(chǔ)空間,而此時(shí)由于捕捉到信號(hào)而插入執(zhí)行該信號(hào)處理程序,其中又調(diào)用malloc,則可能會(huì)對(duì)進(jìn)程造成破壞,因?yàn)閙alloc通常為它所分配的存儲(chǔ)區(qū)維護(hù)一張鏈接表,而插入執(zhí)行信號(hào)處理程序時(shí),進(jìn)程可能正在更改此鏈接表。又例如,若進(jìn)程正在執(zhí)行g(shù)etpwnam這種將其結(jié)果存放在靜態(tài)存儲(chǔ)單元中的函數(shù),其間插入執(zhí)行信號(hào)處理程序,它又調(diào)用這樣的函數(shù),則返回給正常調(diào)用者的信息可能會(huì)被返回給信號(hào)處理程序的信息覆蓋。
沒(méi)有列入表10-3中的大多數(shù)函數(shù)是不可重入的,其原因?yàn)椋海╝)已知它們使用靜態(tài)數(shù)據(jù)結(jié)構(gòu),(b)它們調(diào)用malloc或free,或(c)它們是標(biāo)準(zhǔn)I/O函數(shù)。
應(yīng)當(dāng)了解,即使信號(hào)處理程序調(diào)用的是列于表10-3中的函數(shù),但是由于每個(gè)線程只有一個(gè)errno變量,所以信號(hào)處理程序可能會(huì)修改其原先值。因此,作為一個(gè)通用的規(guī)則,當(dāng)在信號(hào)處理程序中調(diào)用表10-3中列出的函數(shù)時(shí),應(yīng)當(dāng)在其前保存、在其后恢復(fù)errno。
若在信號(hào)處理程序中調(diào)用一個(gè)不可重入函數(shù),則其結(jié)果是不可預(yù)測(cè)的。
本篇博文內(nèi)容摘自《UNIX環(huán)境高級(jí)編程》(第二版),僅作個(gè)人學(xué)習(xí)記錄所用。關(guān)于本書(shū)可參考:http://www.apuebook.com/。
新聞熱點(diǎn)
疑難解答
圖片精選