【中間件】brpc_基礎_用戶態線程中斷

bthread之用戶態線程中斷

源碼

1 簡介

interrupt_pthread 核心功能是 通過信號機制中斷阻塞的 pthread 線程,以實現線程的協作式中斷。


2 核心功能與設計

2.1 信號選擇與注冊

  • 信號選擇:使用 SIGURG 作為中斷信號。
    • 原因SIGURG 通常用于處理帶外數據(Out-of-Band Data),在常規應用中極少被使用,避免與其他信號沖突。
    • 空處理函數do_nothing_handler 不做任何操作,僅用于觸發信號機制。
    void do_nothing_handler(int) {} // 空信號處理器
    

2.2 線程安全初始化

  • 一次性注冊:通過 pthread_once 確保 SIGURG 的信號處理函數 僅注冊一次,避免多線程環境下的重復注冊。
    static pthread_once_t register_sigurg_once = PTHREAD_ONCE_INIT;
    static void register_sigurg() {signal(SIGURG, do_nothing_handler);
    }
    

2.3 中斷線程

  • 發送信號interrupt_pthread 向目標線程發送 SIGURG 信號,觸發中斷。
    int interrupt_pthread(pthread_t th) {pthread_once(&register_sigurg_once, register_sigurg);return pthread_kill(th, SIGURG);
    }
    

3 關鍵機制解析

3.1 中斷阻塞的系統調用

  • EINTR 觸發:當目標線程阻塞在某個系統調用(如 read, write, sleep)時,SIGURG 會中斷該調用,使其返回 EINTR 錯誤碼,線程得以繼續執行后續邏輯。
  • 協作式中斷:線程需檢查 EINTR 并決定是否退出,非強制終止,避免資源泄漏。

3.2 與 bthread 的集成

  • 用戶態線程支持bthread 可能運行在 pthread 之上,中斷 pthread 會影響其管理的所有 bthread
  • 用途:通常用于:
    • 優雅停止服務(如取消長時間阻塞的任務)。
    • 處理超時或取消請求。

4 潛在問題與注意事項

4.1 信號沖突

  • 確保 SIGURG 未被占用:若應用其他模塊使用了 SIGURG,會導致行為沖突。需在項目全局范圍內約定信號用途。
  • 替代方案:可自定義信號(如 SIGUSR1),但需確保跨平臺兼容性。

4.2 可移植性

  • POSIX 依賴:依賴 pthread_killsignal,在非 POSIX 系統(如 Windows)不可用。
  • 信號處理差異:不同 Unix 系統對信號的處理細節可能不同,需充分測試。

4.3 中斷后的處理

  • 錯誤檢查:被中斷的線程需檢查系統調用的返回值,處理 EINTR
    int ret = read(fd, buf, size);
    if (ret == -1 && errno == EINTR) {// 被中斷,執行清理或重試
    }
    
  • 資源清理:確保信號中斷后釋放鎖、關閉文件描述符等資源,避免死鎖或泄漏。

4.4 性能影響

  • 信號處理開銷:頻繁發送信號可能導致性能下降,尤其在多線程高并發場景。
  • 替代方案:考慮使用事件驅動模型(如 epoll)避免阻塞調用。

5 典型應用場景

  1. 服務優雅退出
    void* worker_thread(void* arg) {while (!stopped) {int ret = accept(...);if (ret == -1 && errno == EINTR) {break; // 收到中斷信號,退出循環}// 處理請求}
    }
    
  2. 任務超時控制
    // 設置超時后調用 interrupt_pthread
    set_timeout(100ms, [] { interrupt_pthread(target_thread); });
    

6 總結

函數作用
do_nothing_handler空信號處理函數,僅觸發 EINTR
register_sigurg_once確保信號注冊的線程安全
interrupt_pthread發送 SIGURG 中斷目標線程的阻塞操作

該機制通過輕量級信號實現線程協作式中斷,是 bthread 庫中處理阻塞操作的關鍵設計,但需謹慎處理信號沖突與錯誤恢復,確保系統穩定性。

7 延伸

7.1 SIGURG (Urgent Condition Signal)

SIGURG 是 POSIX 標準定義的信號之一,通常用于處理 帶外數據(Out-of-Band Data, OOB)
在 TCP 通信中,帶外數據用于傳輸緊急消息(如 TCP Urgent Pointer),但現代網絡編程中極少使用此機制,因此 SIGURG 常被保留或用于其他特定用途。

  • 信號編號:在大多數 Unix 系統(如 Linux、macOS)中,SIGURG 的編號為 23
  • 默認行為:默認忽略(SIG_IGN),除非進程顯式注冊處理函數。

在 BRPC/bthread 中的用途
在 Apache BRPC 的 bthread 庫中,SIGURG 被設計為一種 協作式中斷信號,用于中斷阻塞在系統調用(如 readacceptsleep 等)的線程。

其核心機制如下:

  1. 觸發 EINTR
    • 當向目標線程發送 SIGURG 時,若該線程正在執行阻塞系統調用,系統調用會被中斷并返回錯誤碼 EINTR
    • 示例場景
// 線程阻塞在 read 調用
ssize_t ret = read(fd, buf, size);
if (ret == -1 && errno == EINTR) {// 被 SIGURG 中斷,執行清理或退出邏輯
}
  1. 信號處理函數

    • 空處理函數do_nothing_handler 不執行任何操作,僅用于觸發信號機制。
    void do_nothing_handler(int) {} // 僅用于觸發 EINTR
    
    • 避免副作用:由于不修改全局狀態,確保信號處理符合 異步信號安全(Async-Signal-Safe) 要求。
  2. 優勢

    • 低侵入性SIGURG 默認未被應用占用,減少與其他模塊的沖突。
    • 高效性:信號處理開銷極小,僅觸發中斷,無額外邏輯。

潛在風險與注意事項

  1. 信號沖突
  • 問題:若應用其他模塊(如自定義網絡庫)使用 SIGURG,會導致行為沖突。
  • 解決方案
    1. 代碼審查:全局檢查代碼中 SIGURG 的使用情況。
    2. 替換信號:修改 BRPC 源碼,改用其他信號(如 SIGUSR1)。
      // 修改信號注冊代碼
      signal(SIGUSR1, do_nothing_handler); // 替換 SIGURG
      
  1. 平臺兼容性
  • Unix 專屬SIGURG 在 Windows 中不存在,需通過其他機制(如 Event 或 IOCP)實現中斷。
  1. 多線程信號傳遞
  • 精準控制pthread_kill 可定向發送信號到特定線程,避免全局影響。
  • 競態條件:需確保目標線程未退出,否則可能觸發未定義行為。

替代方案對比

方案優點缺點
SIGURG低沖突、輕量級依賴信號機制,平臺限制
SIGUSR1/SIGUSR2用戶自定義,無標準沖突可能被其他庫占用
Eventfd + epoll無信號開銷,兼容性好需修改阻塞邏輯為異步 I/O
Pipe 自中斷完全可控,跨平臺額外文件描述符,復雜度高

實踐建議

  1. 確保信號安全
  • 代碼審查:在項目中禁止隨意使用 SIGURG
  • 文檔標注:明確 SIGURG 被 BRPC 用于中斷機制。
  1. 處理 EINTR
  • 重試邏輯:在關鍵系統調用中循環處理 EINTR
    while (true) {ssize_t ret = read(fd, buf, size);if (ret >= 0) break;if (errno != EINTR) { /* 處理其他錯誤 */ }
    }
    
  1. 調試與監控
  • 信號跟蹤:使用 strace 監控信號傳遞:
    strace -e signal=SIGURG -p <PID>
    
  • 日志記錄:在信號處理函數中添加日志(需確保異步安全):
    void handler(int sig) {const char msg[] = "SIGURG received\n";write(STDERR_FILENO, msg, sizeof(msg)-1);
    }
    

總結
SIGURG 在 BRPC 中作為一種輕量級中斷信號,通過觸發 EINTR 實現線程協作式中斷,但其使用需嚴格避免沖突。開發者應結合應用場景權衡信號機制與其他中斷方案,確保系統穩定性和跨平臺兼容性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904169.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904169.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904169.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux 的網絡卡

#本機操作系統CentOS 10 #核心版本 rootbogon:/etc# uname -r 6.12.0-65.el10.x86_64 網卡能不能被捉到可以使用【dmesg|grep xx】來判斷&#xff0c;有沒有驅動則可以使用lsmod看看模塊有沒有加載核心&#xff01;最后&#xff0c;以ifconfig xxx測試看看 觀察核心所捉到的網卡…

前端雙工通信的幾種方案詳細描述

前端實現雙工通信&#xff08;全雙工或半雙工&#xff09;的常見方案及詳細實現如下&#xff1a; 一、WebSocket&#xff08;全雙工&#xff09; 原理&#xff1a;基于 TCP 的持久化協議&#xff0c;客戶端與服務端建立雙向通信通道&#xff0c;支持實時雙向數據傳輸。 // 客…

KUKA機器人快速啟動設置

KUKA機器人在首次開機啟動時&#xff0c;有時在示教器上需要進行投入運行等相關的設置。如以下相關的信息需要處理&#xff1a; 1、機器人系統開機后&#xff0c;選擇T1運行模式&#xff1b;2、顯示提示信息&#xff1a;“RDC 存儲器和控制系統不一致什么被更換了”時&#xf…

游戲代碼C

以下將結合不同編程語言的特點及游戲開發中的實際應用&#xff0c;展示多種語言的游戲代碼示例&#xff08;以簡單游戲為例&#xff0c;展示代碼結構和邏輯差異&#xff09;。由于代碼篇幅較長&#xff0c;我將分語言進行說明并引用相關來源&#xff1a; 1. C# Unity&#xff…

LangChain Agent核心解析:Zero-Shot-ReAct策略實現與實戰指南

引言 在LangChain的Agent框架中&#xff0c;zero-shot-react-description 是一種預定義的Agent類型&#xff0c;它結合了Zero-Shot&#xff08;零樣本學習&#xff09; 和 ReAct&#xff08;推理行動&#xff09; 策略&#xff0c;主要用于根據工具的描述動態選擇和執行工具&a…

PyQt 或 PySide6 進行 GUI 開發文檔與教程

一、官網文檔 Qt 官方文檔&#xff1a;Porting to Qt 6 | Qt 6.9Qt 維基&#xff1a;???????Qt WikiQt for Python (PySide6) &#xff1a;???????Qt for Python - Qt WikiPySide6 快速上手指南&#xff1a;???????Getting Started - Qt for Python PyS…

2024年第十五屆藍橋杯省賽B組Python【 簡潔易懂題解】

2024年第十五屆藍橋杯省賽B組Python題解 一、整體情況說明 2024年第十五屆藍橋杯省賽B組Python組考試共包含8道題目&#xff0c;分為結果填空題和程序設計題兩類。 考試時間&#xff1a;4小時編程環境&#xff1a;Python 3.x&#xff0c;禁止使用第三方庫&#xff0c;僅可使…

Go語言--語法基礎4--基本數據類型--類型轉換

Go 是一種強類型的語言&#xff0c;所以如果在賦值的時候兩邊類型不一致會報錯。一個類型的值可以被轉換成另一種類型的值。由于 Go 語言不存在隱式類型轉換&#xff0c;因此所有的類型轉換都必須顯式的聲明。 強制類型轉換語法 使用 type (a) 這種形式來進行強制類型轉換&am…

nginx 代理時怎么更改 Remote Address 請求頭

今天工作中遇到用 localhost 訪問網站能訪問后臺 api&#xff0c;但是用本機IP地址后就拒絕訪問&#xff0c;我懷疑是后臺獲取 Remote Address 然后設置白名單了只能 localhost 訪問。 想用 nginx 更改 Remote Address server {listen 8058;server_name localhost;loca…

LeetCode刷題鏈表

文章目錄 鏈表總結 常用技巧兩數相加題解代碼 兩兩交換鏈表中的節點題解代碼 重排鏈表題解代碼 合并k個升序鏈表題解代碼 K個一組翻轉鏈表題解代碼 鏈表總結 常用技巧 畫圖 直觀 形象 便于理解引入虛擬頭節點&#xff0c;便于處理邊界情況&#xff0c;方便我們對鏈表進行…

ESP32S3 多固件燒錄方法、合并多個固件為單一固件方法

ESP32S3 多固件燒錄方法、合并多個固件為單一固件方法 文章目錄 ESP32S3 多固件燒錄方法、合并多個固件為單一固件方法前言1、前期準備工作2、多固件燒錄方法3、單固件燒錄方法總結 前言 使用正點原子的ESP32S3 BOX開發板獨立燒錄編譯生成的xxx.bin固件無法正常運行起來&#…

Webug4.0靶場通關筆記10- 第14關鏈接注入

目錄 第14關 鏈接注入 1.打開靶場 2.源碼分析 3.滲透實戰 &#xff08;1&#xff09;方法1&#xff1a;跳轉外部網頁 &#xff08;2&#xff09;方法2&#xff1a;獲取cookie 4.漏洞防御 本文通過《webug靶場第14關 鏈接注入》來進行滲透實戰。 第14關 鏈接注入 鏈接注…

SpringBoot的汽車商城后臺管理系統源碼開發實現

概述 汽車商城后臺管理系統專為汽車4S店和經銷商設計&#xff0c;提供全面的汽車管理系統解決方案。 主要內容 1. 核心功能模塊 系統提供以下主要功能&#xff1a; ??銷售管理??&#xff1a;記錄銷售信息&#xff0c;跟蹤交易進度??客戶管理??&#xff1a;維護客戶…

VBA代碼解決方案第二十四講:EXCEL中,如何刪除重復數據行

《VBA代碼解決方案》(版權10028096)這套教程是我最早推出的教程&#xff0c;目前已經是第三版修訂了。這套教程定位于入門后的提高&#xff0c;在學習這套教程過程中&#xff0c;側重點是要理解及掌握我的“積木編程”思想。要靈活運用教程中的實例像搭積木一樣把自己喜歡的代碼…

日本IT行業|salesforce開發語言占據的地位

在日本的IT行業中&#xff0c;Salesforce 開發語言處于一個較為專業但穩步增長的細分領域&#xff0c;并不是主流開發語言&#xff08;如 Java、Python、PHP&#xff09;&#xff0c;但其在某些行業和場景中地位越來越重要。 本篇以下是詳細分析&#xff1a; Salesforce開發語言…

前端開發,文件在鏡像服務器上不存在問題:Downloading binary from...Cannot download...

問題與處理策略 問題描述 在 Vue 項目中&#xff0c;執行 npm i 下載依賴時&#xff0c;報如下錯誤 Downloading binary from https://npm.taobao.org/mirrors/node-sass//v4.14.1/win32-x64-72_binding.node Cannot download "https://npm.taobao.org/mirrors/node-sa…

基于Vue2 + Element 實現任務列表管理功能的詳細教程

前言&#xff1a;本文介紹的是如何從0開始搭建Vue2項目到1實現對任務添加、刪除和篩選的功能&#xff0c;&#x1f517; 相關鏈接Vue 入門(安裝與應用超詳細教程) ? 【作者主頁—&#x1f4da;閱讀更多優質文章、獲取更多優質源碼】 目錄 一 . 項目搭建 1.1 安裝node.js 1.…

【PostgreSQL數據分析實戰:從數據清洗到可視化全流程】1.4 數據庫與表的基本操作(DDL/DML語句)

&#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 文章大綱 1.4 數據庫與表的基本操作&#xff08;DDL/DML語句&#xff09;1.4.1 數據庫生命周期管理&#xff08;DDL核心&#xff09;1.4.1.1 創建數據庫&#xff08;CREATE DATABASE&…

Fabrice Bellard(個人網站:?bellard.org?)介紹

Fabrice Bellard 是法國人&#xff0c;國際著名程序員。1972年生于法國Grenoble&#xff0c;大學就讀于巴黎高等綜合理工學院&#xff0c;后在國立巴黎高等電信學院攻讀。 Fabrice Bellard&#xff08;個人網站&#xff1a;?bellard.org?&#xff09;是計算機領域最具影響力…

USB布局布線

1USB簡介 USB是通用串行總線的英文縮寫&#xff0c;是連接外部裝置的一個串口總線標準&#xff0c;也是一種輸入輸出接口的技術規范&#xff0c;被廣泛地應用于個人電腦和移動設備等信息通迅產品&#xff0c;并擴展到攝影器材&#xff0c;數字電視&#xff08;機頂盒&#xff0…