程序通訊基礎03 Linux訊號(一)

2021-10-05 08:51:13 字數 3044 閱讀 5977

struct sigaction結構體

例子

ctrl + c  → 2) sigint(終止/中斷)	 "int" ----interrupt

ctrl + z → 20) sigtstp(暫停/停止) "t" ----terminal 終端。

ctrl + \ → 3) sigquit(退出)

除0操作   → 8) sigfpe (浮點數例外)

"f" -----float 浮點數。

非法訪問記憶體 → 11) sigse** (段錯誤)

匯流排錯誤 → 7) sigbus

核心通過讀取未決訊號集來判斷訊號是否應被處理。訊號遮蔽字mask可以影響未決訊號集。而我們可以在應用程式中自定義set來改變mask。已達到遮蔽指定訊號的目的。

函式定義

sigset_t set;

// typedef unsigned long sigset_t;

int sigemptyset(sigset_t *set);

將某個訊號集清0 成功:0;失敗:-1

int sigfillset(sigset_t *set);

將某個訊號集置1 成功:0;失敗:-1

int sigaddset(sigset_t *set, int signum);

將某個訊號加入訊號集 成功:0;失敗:-1

int sigdelset(sigset_t *set, int signum);

將某個訊號清出訊號集 成功:0;失敗:-1

int sigismember(const sigset_t *set, int signum);

判斷某個訊號是否在訊號集中 返回值:在集合:1;不在:0;出錯:-1

sigset_t

型別的本質是點陣圖。但不應該直接使用位操作,而應該使用上述函式,保證跨系統操作有效。 對比認知select 函式。

用來遮蔽訊號、解除遮蔽也使用該函式。其本質,讀取或修改程序的訊號遮蔽字(pcb中)

嚴格注意,遮蔽訊號:只是將訊號處理延後執行(延至解除遮蔽);而忽略表示將訊號丟處理。

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); 成功:0;失敗:-1,設定errno

讀取當前程序的未決訊號集

int sigpending(sigset_t *set); set傳出引數。 返回值:成功:0;失敗:-1,設定errno

註冊乙個訊號捕捉函式:

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

該函式由ansi定義,由於歷史原因在不同版本的unix和不同版本的linux中可能有不同的行為。因此應該盡量避免使用它,取而代之使用sigaction函式。

修改訊號處理動作(通常在linux用其來註冊乙個訊號的捕捉函式)

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 成功:0;失敗:-1,設定errno

struct sigaction 

;

sa_restorer:該元素是過時的,不應該使用,posix.1標準將不指定該元素。(棄用)

sa_sigaction:當sa_flags被指定為sa_siginfo標誌時,使用該訊號處理程式。(很少使用)

重點掌握:

① sa_handler:指定訊號捕捉後的處理函式名(即註冊函式)。也可賦值為sig_ign表忽略 或 sig_dfl表執行預設動作

② sa_mask: 呼叫訊號處理函式時,所要遮蔽的訊號集合(訊號遮蔽字)。注意:僅在處理函式被呼叫期間遮蔽生效,是臨時性設定。

③ sa_flags:通常設定為0,表使用預設屬性。

程序正常執行時,預設pcb中有乙個訊號遮蔽字,假定為☆,它決定了程序自動遮蔽哪些訊號。當註冊了某個訊號捕捉函式,捕捉到該訊號以後,要呼叫該函式。而該函式有可能執行很長時間,在這期間所遮蔽的訊號不由☆來指定。而是用sa_mask來指定。呼叫完訊號處理函式,再恢復為☆。

***訊號捕捉函式執行期間,***訊號自動被遮蔽。

阻塞的常規訊號不支援排隊,產生多次只記錄一次。(後32個實時訊號支援排隊)

訊號

#include

#include

#include

#include

#include

#include

#include

#include

void

print_set

(sigset_t& set)

std::cout << std::endl;

}int

main()

return0;

}

#include

#include

#include

#include

#include

#include

#include

#include

void

catch_signal

(int sign)

}int

main()

while

(true);

return0;

}

#include

#include

#include

#include

#include

#include

#include

#include

#include

void

catch_signal

(int sign)}}

intmain()

if(pid ==0)

;}else

return i;

}

03 linux下程序通訊 共享記憶體

接下來我們介紹一種簡單而高效的程序間通訊的方式!共享記憶體 注意了是通訊也就是資料交換,如果要想避免同時讀寫發生的同步問題就得需要其他機制!在實際程式設計中,常用的同步機制有 訊號量 傳遞訊息 使用管道或ipc訊息 生成訊號。但是在這次的實現裡面我們用自己提供的非常醜陋的同步標誌written by...

03 Linux常用基礎命令(二)

目錄 1.檢視命令型別 2.命令別名 3.which 4.whereis 5.who 6.w 注 本系統環境為centos 7 命令型別 外部命令 shell內部命令 命令格式 type command 內部 builtin 內建 外部 顯示為命令檔案路徑 注意 命令可以有別名 別名可以與原名相同,...

03 Linux 檔案管理

談及到 linux 檔案管理,首先我們需要了解的就是,我們要對檔案做些什麼事情?其實無非就是對乙個檔案進行建立 複製 移動 檢視 編輯 壓縮 檢視 刪除等等 首先我們知道 linux 的目錄結構為樹狀結構,最頂級的目錄為根目錄 其他目錄通過掛載可以將它們新增到樹中,通過解除掛載可以移除它們,以此類推...