)
信號生命周期圖解Coursebook一課看懂信號流轉(zhuǎn)【免費下載鏈接】coursebookOpen Source Introductory Systems Programming Textbook for the University of Illinois項目地址: https://gitcode.com/GitHub_Trending/co/coursebook對于想搞懂 Linux 系統(tǒng)編程的初學(xué)者來說信號Signal是最容易繞暈的概念之一。本文基于伊利諾伊大學(xué)開源教材Coursebook的 Signals 章節(jié)用一張流程圖 一張時序圖帶你一次性看懂信號的生命周期它如何被生成Generated、掛起Pending、被阻塞Blocked、交付Delivered最終被捕獲Caught或殺死進(jìn)程Killed。零基礎(chǔ)也能一圖通關(guān)。圖中紅色流程就是完整鏈路Generated → Pending → Delivered → Caught/Killed藍(lán)色分支表示信號被阻塞Blocked解除阻塞后才會繼續(xù)交付。什么是信號為什么它很重要簡單說信號就是操作系統(tǒng)異步發(fā)送給進(jìn)程的低優(yōu)先級消息比如你在終端按下Ctrl-C就是給程序發(fā)了一個 SIGINT 信號。Coursebook 特別強(qiáng)調(diào)兩點幫你避開常見誤區(qū) 信號 ≠ 硬件中斷。這里的信號本質(zhì)是內(nèi)核生成的軟中斷可能由硬件事件觸發(fā)比如非法訪存引發(fā) SIGSEGV信號主要用于終止和清理不適合用來寫核心程序邏輯。信號生命周期的 4 個關(guān)鍵狀態(tài)結(jié)合 signals/signals.tex 中的描述一條信號的完整流轉(zhuǎn)是Generated生成信號被創(chuàng)建來源可能是用戶按鍵、內(nèi)核事件或其他進(jìn)程Pending掛起信號已生成等待內(nèi)核應(yīng)用掩碼規(guī)則——這是出生到排隊的過渡期Blocked阻塞可選分支如果進(jìn)程中所有線程都在屏蔽該信號它就卡在阻塞態(tài)直到有人解除阻塞Delivered交付只要有一個線程能接收內(nèi)核就打斷該線程跳去執(zhí)行處置動作終止、忽略、core dump、停止、繼續(xù)或執(zhí)行自定義處理函數(shù)Caught / Killed結(jié)局進(jìn)程安然無恙則算捕獲否則直接陣亡。?? 記住兩條鐵律SIGKILL 和 SIGSTOP 永遠(yuǎn)無法被捕獲、阻塞或忽略正在執(zhí)行處理函數(shù)期間新信號可以生成但要等處理完才能繼續(xù)交付。常見信號速查表SIGINT、SIGTERM、SIGKILL 怎么選信號編號默認(rèn)動作典型用途SIGINT2終止可捕獲體面地停止進(jìn)程Ctrl-CSIGQUIT3終止可捕獲更直接地停止SIGTERM15終止進(jìn)程最常用的請退出SIGSTOPN/A停止進(jìn)程不可捕獲凍結(jié)進(jìn)程SIGCONTN/A繼續(xù)進(jìn)程從停止中恢復(fù)SIGKILL9終止進(jìn)程不可捕獲必須讓進(jìn)程立刻消失為什么書上勸你別動不動kill -9因為 SIGKILL 不給進(jìn)程任何清理機(jī)會關(guān)閉 socket、清理臨時文件、通知子進(jìn)程、重置終端……全都做不了。教科書里的建議是先kill -15等一兩秒不行再kill -2再不行刪掉這個行為不端的程序。別為了整理花盆出動聯(lián)合收割機(jī) 。信號從哪里來三種發(fā)送方式Coursebook 總結(jié)了信號生成的三個來源用戶發(fā)送終端按Ctrl-C或用 shell 的kill命令系統(tǒng)事件內(nèi)核檢測到非法內(nèi)存訪問就發(fā) SIGSEGV子進(jìn)程狀態(tài)變化也會觸發(fā)信號其他進(jìn)程進(jìn)程間可以用信號做輕量級事件通知但教材提醒——別把信號當(dāng)通信主力正經(jīng)的進(jìn)程間通信IPC有專門機(jī)制。順帶一提SIGSTOP可以讓進(jìn)程徹底凍結(jié)不再分配 CPU 時間SIGCONT讓它復(fù)活。而且非 root 用戶只能給同一用戶的進(jìn)程發(fā)信號不能想殺誰就殺誰。處理信號的正確姿勢只設(shè)標(biāo)志別干重活這是新手最容易踩的坑 ?信號處理函數(shù)里能用的庫函數(shù)非常有限大多數(shù)函數(shù)都是異步信號不安全的——因為處理函數(shù)可能在任何時刻被再次打斷。教材給的經(jīng)典案例你在func里printf時被打斷恢復(fù)執(zhí)行后發(fā)現(xiàn)緩沖區(qū)已被處理函數(shù)改寫輸出World而不是原本該有的Hello。安全的設(shè)計模式是處理函數(shù)里只設(shè)置一個volatile sig_atomic_t標(biāo)志位讓主循環(huán)檢查后自行退出并清理。同時建議用sigaction而不是signal后者在不同系統(tǒng)上行為不一致想屏蔽信號用sigprocmask/pthread_sigmask想同步等待信號用sigwait它還能讓你在處理線程里安全地調(diào)用各種庫函數(shù)。子進(jìn)程與線程里的信號繼承規(guī)則信號在fork和線程間的行為有一條容易混淆的規(guī)則看這張時序圖就清晰了fork 之后子進(jìn)程繼承父進(jìn)程的信號處置和掩碼但不繼承掛起中的信號exec 之后只保留信號掩碼和掛起信號處理函數(shù)全部重置為默認(rèn)多線程每個線程有自己的掩碼新線程繼承創(chuàng)建者的掩碼但信號處置是進(jìn)程級的——任何一個線程注冊處理函數(shù)全進(jìn)程生效。所以最佳實踐是在創(chuàng)建新線程之前先在主線程里用pthread_sigmask屏蔽要統(tǒng)一處理的信號再讓一個專門的線程用sigwait接收。如何在 Coursebook 中繼續(xù)深挖信號信號章節(jié)完整源碼signals/signals.tex配套文獻(xiàn) signals/signals.bib進(jìn)程與fork/exec/wait基礎(chǔ)processes/processes.tex信號退出狀態(tài)的讀取也在這里全書章節(jié)順序可在 order.yaml 中查看Signals 排在第 13 章正好在進(jìn)程、線程、同步、IPC 之后知識鋪墊完整術(shù)語定義參考 glossary.tex如 POSIX、Linux Kernel 條目。 一句話總結(jié)信號的生命周期 生成 → 掛起 →可能阻塞→ 交付 → 捕獲或終止。抓住這條主線再記住SIGKILL 不可捕獲、處理函數(shù)保持極簡兩條原則Coursebook 這一課的信號流轉(zhuǎn)你就真正看懂了。【免費下載鏈接】coursebookOpen Source Introductory Systems Programming Textbook for the University of Illinois項目地址: https://gitcode.com/GitHub_Trending/co/coursebook創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考