環境程式設計05

2021-10-09 10:36:23 字數 3586 閱讀 3185

基本概念

1、中斷

當程式接收訊息後中止當前正在執行的程式,轉而執行其它任務,等其它任務執行完成後再返回,這種執行模式叫中斷,分為硬體中斷和軟體中斷。

2、訊號

是一種軟體中斷,由作業系統發出,程式接收後會執行相應的操作。

3、常見訊號

kill -l 顯示所有訊號

sigint ctrl+c 終止

sigquit ctrl+\ 終止+core

sigfpe 除0 終止+core

sigse** 非常記憶體訪問 終止+core

sigkill 終止訊號 終止

4、不可靠訊號和可靠訊號

建立在早期的訊號處理機制上(1~31) 是不可靠訊號。

不支援排除,可能會丟失,同乙個訊號如果連續產生多次,程序可能只接收到一次。

建立在新訊號處理機制上 (34~64) 是可靠訊號,支援排除,不會丟失。

5、訊號**

硬體異常:除0、無效記憶體訪問、未定義指令、匯流排錯誤、軟體異常。

軟體異常:通過一些命令、函式產生的訊號。

6、訊號的處理方式

1、忽略

2、終止程序

3、終止程序並產生core檔案

4、捕獲並處理(當訊號發前,向核心註冊乙個函式,當訊號發生時系統自動執行該函式)。

訊號捕獲:

typedef void (*sighandler_t)(int);

功能:訊號處理函式的格式

sighandler_t signal(int signum, sighandler_t handler);

功能:向訊號註冊乙個訊號處理函式

signum:訊號編號

handler:函式指標

sig_ign 忽略

sig_dfl 按預設處理

返回值:

之前的訊號處理方式

注意:有些系統通過signal註冊的函式只執行一次,如果想持續有效,可以在訊號處理函式中再註冊一次。

注意:子程序會繼承父程序的訊號處理方式,但如果是通過exec系列函式建立的子程序,會恢復預設的訊號處理式。

注意:訊號處理完後會返回到產生訊號的**處理,如果我們捕獲並處理段錯誤或算術異常可能會產生死迴圈,正確處理段錯誤和算術異常應該是備份資料並結束程序。

練習1:測試一下哪些訊號不能**獲處理。

sigkill(9),sigstop(19)

訊號的傳送:

鍵盤:ctrl+c

ctrl+

ctrl+z

錯誤:除0

非法記憶體訪問

硬體故障 匯流排錯誤

命令:kill 訊號 程序號

killall 訊號 程序名

函式:int kill(pid_t pid, int sig);

功能:向指定的程序傳送訊號

int raise(int sig);

功能:向程序自己傳送訊號

void abort(void);

功能:向程序自己傳送sigabrt訊號

unsigned int alarm(unsigned int seconds);

功能:讓核心在seconds後向程序發關這sigalrm訊號

返回值:上次alarm設定的剩餘時間

注意:如果再次呼叫會覆蓋之前的設定,而不會產生兩次鬧鐘訊號。

程序休眠與訊號:

int pause(void);

功能:讓呼叫者進入休眠狀態,直接程序遇到訊號(捕獲處理、程序結束)

返回值:要麼一直休眠不返回,要麼返回-1。

相當於沒有時間限制的sleep

unsigned int sleep(unsigned int seconds);

功能:讓呼叫者進入休眠指定的秒數,當遇到訊號時會提前返回。

返回值:剩餘的休眠時間

訊號集與訊號阻塞:

訊號集:是一種資料型別,可以儲存多個訊號。

sigset_t 128二進位制,每一次都**乙個訊號。

相關函式:

int sigemptyset(sigset_t *set);

功能:清空訊號集

int sigfillset ( sigset_t *set);

功能:填滿訊號集

int sigaddset(sigset_t *set, int signum);

功能:向訊號集中新增訊號

int sigdelset(sigset_t *set, int signum);

功能:從訊號集中刪除訊號

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

功能:測試訊號集中是否有某個訊號

功能:0 不存在

1 存在

-1 訊號非法

訊號阻塞:

當程式在執行一些特殊操作時是不適合處理訊號的,此時可以讓核心先遮蔽訊號,等操作執行完成後再傳送訊號。

當訊號產生時,核心會在其所維護訊號表中為程序設定乙個與該訊號對應的標記,這個過程叫遞送。

從訊號產生到完成遞送有個時間間隔,處於這個間隔的訊號狀態叫未決。

訊號遮蔽就是讓訊號先處於未決狀態,暫停遞送,當遮蔽解除時再繼續遞送。

每個程序都有乙個訊號集用於儲存要遮蔽的訊號。

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

功能:設定要遮蔽的訊號,這些訊號儲存在訊號集裡面。

how:

sig_block 把set中的訊號新增到要遮蔽的訊號集裡。

sig_unblock 從訊號集刪除set的訊號。

sig_setmask 用set替換之前的訊號集。

set:準備好的訊號集

oldset:獲取的訊號的集

int sigpending(sigset_t *set);

功能:獲取未決狀態的訊號

帶附加的訊號處理:

int sigaction(int signum, const struct sigaction *act,

struct sigaction *oldact);

功能:向核心註冊乙個訊號處理方式

signum:要捕獲的訊號

act:訊號處理函式

oldact:獲取舊的訊號處理式

struct sigaction ;

siginfo_t ;

定時器:

int getitimer(int which, struct itimerval *curr_value);

功能:獲取當前的定時方案

which:

itimer_real 真實計時器,程式總的執行時間 sigalrm

itimer_virtual 虛擬計時器 使用者態的執行時間 sigalrm

itimer_prof 實際計時器 使用者態+核心態的執行時間 sigprof

真實計時器 = 實際計時器 + 休眠時間

int setitimer(int which, const struct itimerval *new_value,

struct itimerval *old_value);

功能:設定新的定義方案

struct itimerval ;

struct timeval ;

團體程式設計天梯賽 05

每個pat考生在參加考試時都會被分配兩個座位號,乙個是試機座位,乙個是考試座位。正常情況下,考生在入場時先得到試機座位號碼,入座進入試機狀態後,系統會顯示該考生的考試座位號碼,考試時考生需要換到考試座位就座。但有些考生遲到了,試機已經結束,他們只能拿著領到的試機座位號碼求助於你,從後台查出他們的考試...

05用d程式設計切片

切片,動態陣列的別名.起.尾 是這樣的 即左包右不包 切片不是實體,就像鑰匙一樣.如果切片修改實體,則實體也跟著變了.a.a 大小為0,a.表示陣列長度,等價於陣列.長度.dup複製實體.如下 import std.stdio void main 賦值 int 3 a 1 1,1 int 3 b 2...

力扣程式設計題05

面試題05.替換空格 請實現乙個函式,把字串 s 中的每個空格替換成 20 示例 1 限制 0 s 的長度 10000 class solution 1221.分割平衡字串 在乙個 平衡字串 中,l 和 r 字元的數量是相同的。給出乙個平衡字串 s,請你將它分割成盡可能多的平衡字串。返回可以通過分割...