<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 信號,第 2 部分:待處理的信號和信號掩碼 > 原文:<https://github.com/angrave/SystemProgramming/wiki/Signals%2C-Part-2%3A-Pending-Signals-and-Signal-Masks> ## 信號深度 ## 如何了解有關信號的更多信息? linux 手冊頁討論了第 2 節中的信號系統調用。第 7 節中還有一篇較長的文章(盡管不在 OSX / BSD 中): ``` man -s7 signal ``` ## 信號術語 * 生成 - 通過 kill 系統調用在內核中創建信號。 * 待定 - 尚未交付但很快將交付 * 已阻止 - 未傳送,因為沒有信號處理可以傳送信號 * 交付 - 交付過程,正在采取所述行動 * 抓住 - 當進程停止信號來摧毀它并用它做其他事情時 ## 什么是進程的信號處理? 對于每個過程,每個信號都有一個配置,這意味著當信號傳遞給過程時會發生什么動作。例如,默認處置 SIGINT 是終止它。信號處理可以通過調用 signal()來改變(這是簡單但不可移植的,因為它在不同的 POSIX 架構上的實現有細微的變化,也不推薦用于多線程程序)或`sigaction`(稍后討論)。您可以將過程對所有可能信號的處置想象為函數指針條目表(每個可能的信號一個)。 信號的默認處置可以是忽略信號,停止進程,繼續停止進程,終止進程,或終止進程并轉儲'核心'文件。請注意,核心文件是可以使用調試器檢查的進程內存狀態的表示。 ## 多個信號可以排隊嗎? 否 - 但是可能有信號處于掛起狀態。如果信號處于待處理狀態,則表示尚未交付給該進程。信號待決的最常見原因是進程(或線程)當前阻止了該特定信號。 如果是特定信號,例如 SIGINT 正在等待,因此無法再次排隊相同的信號。 可能在待處理狀態下具有多個不同類型的信號。例如,SIGINT 和 SIGTERM 信號可能正在等待(即尚未傳送到目標進程) ## 如何阻止信號? 通過設置過程信號掩碼,或者在編寫多線程程序時,可以阻止信號(意味著它們將保持在掛起狀態),線程信號掩碼。 ## 線程/子項中的處置 ## 創建新線程時會發生什么? 新線程繼承了調用線程掩碼的副本 ```c pthread_sigmask( ... ); // set my mask to block delivery of some signals pthread_create( ... ); // new thread will start with a copy of the same mask ``` ## 分叉時會發生什么? 子進程繼承父進程信號處理的副本。換句話說,如果您在分叉之前安裝了 SIGINT 處理程序,那么如果將 SIGINT 傳遞給子進程,子進程也將調用處理程序。 注意孩子的待處理信號是 _ 而不是 _ 在分叉期間繼承的。 ## exec 期間會發生什么? 信號掩碼和信號配置都轉移到執行程序。 [https://www.gnu.org/software/libc/manual/html_node/Executing-a-File.html#Executing-a-File](Source) 也會保留待處理信號。信號處理程序被重置,因為原始處理程序代碼與舊進程一起消失。 ## 叉期間會發生什么? 子進程繼承父進程的信號處理副本和父進程信號掩碼的副本。 例如,如果在父母中阻止`SIGINT`,它也將在孩子中被阻止。例如,如果父級為 SIG-INT 安裝了處理程序(回調函數),則子級也將執行相同的行為。 然而,待定信號不是由孩子繼承的。 ## 如何在單線程程序中阻止信號? 使用`sigprocmask`!使用 sigprocmask,您可以設置新掩碼,將要阻止的新信號添加到進程掩碼,以及取消阻止當前阻塞的信號。您還可以通過傳入 oldset 的非 null 值來確定現有掩碼(并在以后使用它)。 ``` int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);` ``` 從 sigprocmask 的 Linux 手冊頁, ``` SIG_BLOCK: The set of blocked signals is the union of the current set and the set argument. SIG_UNBLOCK: The signals in set are removed from the current set of blocked signals. It is permissible to attempt to unblock a signal which is not blocked. SIG_SETMASK: The set of blocked signals is set to the argument set. ``` sigset 類型表現為位圖,除了使用函數而不是使用&amp;顯式設置和取消設置位。和|。 在修改一位之前忘記初始化信號集是一個常見的錯誤。例如, ```c sigset_t set, oldset; sigaddset(&set, SIGINT); // Ooops! sigprocmask(SIG_SETMASK, &set, &oldset) ``` 正確的代碼將該集初始化為全部打開或全部關閉。例如, ```c sigfillset(&set); // all signals sigprocmask(SIG_SETMASK, &set, NULL); // Block all the signals! // (Actually SIGKILL or SIGSTOP cannot be blocked...) sigemptyset(&set); // no signals sigprocmask(SIG_SETMASK, &set, NULL); // set the mask to be empty again ``` ## 如何在多線程程序中阻止信號? 多線程程序中的阻塞信號類似于單線程程序: * 使用 pthread_sigmask 而不是 sigprocmask * 阻止所有線程中的信號以防止其異步傳遞 確保信號在所有線程中被阻止的最簡單方法是在創建新線程之前在主線程中設置信號掩碼 ```c sigemptyset(&set); sigaddset(&set, SIGQUIT); sigaddset(&set, SIGINT); pthread_sigmask(SIG_BLOCK, &set, NULL); // this thread and the new thread will block SIGQUIT and SIGINT pthread_create(&thread_id, NULL, myfunc, funcparam); ``` 正如我們在 sigprocmask 中看到的那樣,pthread_sigmask 包含一個'how'參數,用于定義如何使用信號集: ```c pthread_sigmask(SIG_SETMASK, &set, NULL) - replace the thread's mask with given signal set pthread_sigmask(SIG_BLOCK, &set, NULL) - add the signal set to the thread's mask pthread_sigmask(SIG_UNBLOCK, &set, NULL) - remove the signal set from the thread's mask ``` ## 如何在多線程程序中提供待處理信號? 信號被傳送到任何未阻塞該信號的信號線程。 如果兩個或多個線程可以接收信號,那么哪個線程將被中斷是任意的!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看