java開發(fā)手機網(wǎng)站開發(fā)??诰W(wǎng)站關鍵詞優(yōu)化
問題
如何編寫信號安全的應用程序?
Linux 應用程序安全性討論
場景一:不需要處理信號
- 應用程序實現(xiàn)單一功能,不需要關注信號
- 如:數(shù)據(jù)處理程序,文件加密程序,科學計算程序
場景二:需要處理信號
- 應用程序長時間運行,需要關注信號,并即使處理
- 如:服務端程序,上位機程序
場景一:不需要信號處理 (單一功能應用程序)
場景二:需要處理信號 (長時間運行的應用)
同步方案
- 通過標記同步處理信號,整個應用中只有一個執(zhí)行流
異步方案
- 專用任務處理,應用中存在多個執(zhí)行流 (多線程應用)
- 設置專用信號處理任務,其它任務忽略信號,專注功能實現(xiàn)
同步解決方案 (單任務)
信號處理邏輯與程序邏輯位于同一個上下文
- 即:信號處理函數(shù)和主函數(shù)不存在資源競爭關系
方案設計一
- 將任務分解為子任務(每個任務可對應一個函數(shù))
- 信號遞達時,信號處理函數(shù)中僅標記遞達狀態(tài)
- 子任務處理結束后,真正執(zhí)行信號處理
同步方案示例一
存在的問題
由于給每個信號唯一的標記位置,因此,所有信號轉變?yōu)椴豢煽啃盘?#xff1b;并且僅保留最近遞達的信號信息
方案設計二
將任務分解為子任務 (每個任務可對應一個函數(shù))
- 創(chuàng)建信號文件描述符,并阻塞所有信號 (可靠信號遞達前位于內核隊列中)
- 子任務處理結束后,通過 select 機制判斷是否有信號需要處理
- true => 處理信號? false => 等待超時
關鍵系統(tǒng)函數(shù)
#include <sys/select.h>
#include <sys/signalfd.h>
int signalfd(int fd, const sigset_t* mask, int flag);
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout);
使用 signalfd() 處理信號
先屏蔽所有信號 (無法遞達進程),之后為屏蔽信號創(chuàng)建文件描述符;當時機成熟,通過 read() 系統(tǒng)調用讀取未決信號 (主動接收信號)
使用 select() 監(jiān)聽文件描述符
使用 select() 處理信號
存在的問題
由于使用了 select 機制,即便沒有信號需要處理,也需要等待 select 超時,任務實時性受到影響
異步解決方案 (多任務)
使用獨立任務處理信號,程序邏輯在其他任務中執(zhí)行
即:通過多線程分離信號處理與程序邏輯
- 主線程:專用于信號處理
- 其他線程:完成程序功能
多線程信號處理
信號的發(fā)送目標是進程,而不是某個特定的線程
發(fā)送給進程的信號僅遞送給一個進程
內核從不會阻塞目標信號的線程中隨機選擇
每個線程擁有獨立的信號屏蔽掩碼
異步解決方案 (多任務)
主線程:對目標信號設置信號處理的方式
- 當信號遞達進程時,只可能時主線程進行信號處理
其他線程:首先屏蔽所有可能的信號,之后執(zhí)行任務代碼
- 無法接收到信號,不具備信號處理能力
進程與線程
進程:應用程序的一次加載執(zhí)行 (系統(tǒng)執(zhí)行資源分配的基本單位)
線程:進程中的程序執(zhí)行流
- 一個進程中可以存在多個線程 (至少存在一個線程)
- 每個線程執(zhí)行不同的任務 (多個線程可并行執(zhí)行)
- 同一個進程中的多個線程共享進程的系統(tǒng)資源
Linux 多線程 API 函數(shù)
頭文件:#include<pthread.h>
線程創(chuàng)建函數(shù):int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine)(void*), void* arg);
- thread:pthread_t 變量的地址,用于返回線程標識
- attr:線程的屬性,可設置為 NULL,即:使用默認屬性
- start_routine:線程入口函數(shù)
- arg:線程入口函數(shù)參數(shù)
線程標識:
- pthread_t pthread_self(void);
- 獲取當前線程的 ID 標識
線程等待:
- int pthread_join(pthread_t thread, void** retval);
- 等待目標線程執(zhí)行結束
多線程編程示例
異步方案示例 -- 主線程
異步方案示例 -- 任務線程
信號設計模式小結
多數(shù)模式不需要處理信號,因此可直接屏蔽信號
需要處理信號的程序,重點考慮信號安全性問題
- 同步處理方案,通過設計讓任務代碼和信號處理代碼交替執(zhí)行
- 問題:信號處理是否及時?任務執(zhí)行是否實時?
- 異步處理方案,任務代碼與信號處理代碼位于不同執(zhí)行流
- 問題:將信號安全性問題轉換為線程安全性問題
- 因此,程序本身是否能做到線程安全?