亚洲精品一二区_国产黄色片网站_99久久久成人国产精品_蜜臀网_国产精品一区二区三区免费_成人av中文字幕_91精品国产欧美一区二区成人

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 學習筆記 > 嵌入式學習筆記:linux進程通信之信號函數

嵌入式學習筆記:linux進程通信之信號函數 時間:2018-09-26      來源:未知

1、信號注冊函數: signal

#include

void (*signal(int signum, void (*sighandler_t)(int))) (int); typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

入參:

signum 哪個信號

handle 信號所對應的處理函數;SIG_IGN:忽略此信號;SIG_DFL:按系統默認

方式處理

該函數由ANSI定義,由于歷史原因在不同版本的Unix和不同版本的Linux中可能有不同的行為。因此應該盡量避免使用它,取而代之使用sigaction函數。

2、修改信號處理動作(通常在Linux用其來注冊一個信號的捕捉函數)

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

成功:0;失敗:-1,設置errno

參數:

act:傳入參數,新的處理方式。

oldact:傳出參數,舊的處理方式。

struct sigaction結構體

struct sigaction {

void

void

sigset_t

int

void

(*sa_handler)(int);

(*sa_sigaction)(int, siginfo_t *, void *);

sa_mask;

sa_flags;

(*sa_restorer)(void);

};

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

sa_sigaction:當sa_flags被指定為SA_SIGINFO標志時,使用該信號處理程序。(很少使用)

重點掌握:

① sa_handler:指定信號捕捉后的處理函數名(即注冊函數)。也可賦值為SIG_IGN表忽略 或 SIG_DFL表執行默認動作

② sa_mask: 調用信號處理函數時,所要屏蔽的信號集合(信號屏蔽字)。注意:僅在處理函數被調用期間屏蔽生效,是臨時性設置。

③ sa_flags:通常設置為0,表使用默認屬性。

內核實現信號捕捉過程:

信號捕捉特性:

1、進程正常運行時,默認PCB中有一個信號屏蔽字,假定為☆,它決定了進程自動屏蔽哪些信號。當注冊了某個信號捕捉函數,捕捉到該信號以后,要調用該函數。而該函數有可能執行很長時間,在這期間所屏蔽的信號不由☆來指定。而是用sa_mask來指定。調用完信號處理函數,再恢復為☆。

2、XXX信號捕捉函數執行期間,XXX信號自動被屏蔽。

3、阻塞的常規信號不支持排隊,產生多次只記錄一次。(后32個實時信號支持排

隊)

3、pause函數 : 掛起當前的進程,直到收到一個信號,才會接著執行

調用該函數可以造成進程主動掛起,等待信號喚醒。調用該系統調用的進程將處于阻塞狀態(主動放棄cpu) 直到有信號遞達將其喚醒。

int pause(void);

返回值:-1 并設置errno為EINTR

① 如果信號的默認處理動作是終止進程,則進程終止,pause函數么有機會返回。 ② 如果信號的默認處理動作是忽略,進程繼續處于掛起狀態,pause函數不返回。 ③ 如果信號的處理動作是捕捉,則【調用完信號處理函數之后,pause返回-1】errno設置為 EINTR,表示“被信號中斷”。想想我們還有哪個函數只有出錯返回

值。

④ pause收到的信號不能被屏蔽,如果被屏蔽,那么pause就不能被喚醒。

4、alarm函數

設置定時器(鬧鐘)。在指定seconds后,內核會給當前進程發送14)SIGALRM信號。進程收到該信號,默認動作終止。

每個進程都有且只有唯一個定時器。

unsigned int alarm(unsigned int seconds);

返回0或剩余的秒數,無失敗。

常用:取消定時器alarm(0),返回舊鬧鐘余下秒數。

例:alarm(5) → 3sec → alarm(4) → 5sec → alarm(5) → alarm(0)

定時,與進程狀態無關(自然定時法)!就緒、運行、掛起(阻塞、暫停)、終止、僵尸...無論進程處于何種狀態,alarm都計時。

使用time命令查看程序執行的時間。程序運行的瓶頸在于IO,優化程序,首選優化IO。

實際執行時間 = 系統時間 + 用戶時間 + 等待時間

5、raise函數: 自己給自己發送信號 raise(signo) == kill(getpid(), signo);

int raise(int sig);

成功:0,失敗非0值

入參: 發送的信號

6、abort 函數:給自己發送異常終止信號 6) SIGABRT 信號,終止并產生core文件 void abort(void); //該函數無返回

kill函數/命令產生信號

1、kill命令產生信號:kill -SIGKILL pid

2、kill函數:給指定進程發送指定信號(不一定殺死)

7、int kill(pid_t pid, int sig);

成功:0;失敗:-1 (ID非法,信號非法,普通用戶殺init進程等權級問題),設置errno sig:不推薦直接使用數字,應使用宏名,因為不同操作系統信號編號可能不同,但名稱一致。

pid > 0: 發送信號給指定的進程。

pid = = 0: 發送信號給 與調用kill函數進程屬于同一進程組的所有進程。

pid < 0: 取|pid|發給對應進程組。

pid = = -1:發送給進程有權限發送的系統中所有進程。

進程組:每個進程都屬于一個進程組,進程組是一個或多個進程集合,他們相互關聯,共同完成一個實體任務,每個進程組都有一個進程組長,默認進程組ID與進程組長ID

相同。

權限保護:super用戶(root)可以發送信號給任意用戶,普通用戶是不能向系統用戶發送信號的。 kill -9 (root用戶的pid) 是不可以的。同樣,普通用戶也不能向其他

普通用戶發送信號,終止其進程。 只能向自己創建的進程發送信號。普通用戶基本規則是:發送者實際或有效用戶ID == 接收者實際或有效用戶ID

 

時序競態

設想如下場景:

欲睡覺,定鬧鐘10分鐘,希望10分鐘后鬧鈴將自己喚醒。

正常:定時,睡覺,10分鐘后被鬧鐘喚醒。

異常:鬧鐘定好后,被喚走,外出勞動,20分鐘后勞動結束。回來繼續睡覺計劃,但勞動期間鬧鐘已經響過,不會再將我喚醒。

時序問題分析

回顧,借助pause和alarm實現的mysleep函數。設想如下時序:

1. 注冊SIGALRM信號處理函數 (sigaction...)

2. 調用alarm(1) 函數設定鬧鐘1秒。

3. 函數調用剛結束,開始倒計時1秒。當前進程失去cpu,內核調度優先級高的進程(有多個)取代當前進程。當前進程無法獲得cpu,進入就緒態等待cpu。

4. 1秒后,鬧鐘超時,內核向當前進程發送SIGALRM信號(自然定時法,與進程狀態無

關),高優先級進程尚未執行完,當前進程仍處于就緒態,信號無法處理(未決)

5. 優先級高的進程執行完,當前進程獲得cpu資源,內核調度回當前進程執行。

SIGALRM信號遞達,信號設置捕捉,執行處理函數sig_alarm。

6. 信號處理函數執行結束,返回當前進程主控流程,pause()被調用掛起等待。(欲

等待alarm函數發送的SIGALRM信號將自己喚醒)

7. SIGALRM信號已經處理完畢,pause不會等到。

解決時序問題

可以通過設置屏蔽SIGALRM的方法來控制程序執行邏輯,但無論如何設置,程序都有可能在“解除信號屏蔽”與“掛起等待信號”這個兩個操作間隙失去cpu資源。除非將這兩步驟合并成一個“原子操作”。sigsuspend函數具備這個功能。在對時序要求嚴格的場

合下都應該使用sigsuspend替換pause。

int sigsuspend(const sigset_t *mask);//掛起等待信號。

sigsuspend函數調用期間,進程信號屏蔽字由其參數mask指定。

可將某個信號(如SIGALRM)從臨時信號屏蔽字mask中刪除,這樣在調用sigsuspend時將解除對該信號的屏蔽,然后掛起等待,當sigsuspend返回時,進程的信號屏蔽字恢復為原來的值。如果原來對該信號是屏蔽態,sigsuspend函數返回后仍然屏蔽該信號。

競態條件,跟系統負載有很緊密的關系,體現出信號的不可靠性。系統負載越嚴重,信號不可靠性越強。

不可靠由其實現原理所致。信號是通過軟件方式實現(跟內核調度高度依賴,延時性強),每次系統調用結束后,或中斷處理處理結束后,需通過掃描PCB中的未決信號集,來判斷是否應處理某個信號。當系統負載過重時,會出現時序混亂。

這種意外情況只能在編寫程序過程中,提早預見,主動規避,而無法通過gdb程序調試等其他手段彌補。且由于該錯誤不具規律性,后期捕捉和重現十分困難。

8、setitimer函數

設置定時器(鬧鐘)。 可代替alarm函數。精度微秒us,可以實現周期定時。

int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);

成功:0;失敗:-1,設置errno

參數:which:指定定時方式

① 自然定時:ITIMER_REAL → 14)SIGLARM 計算自然時間

② 虛擬空間計時(用戶空間):ITIMER_VIRTUAL → 26)SIGVTALRM 只計算進程占

用cpu的時間

③ 運行時計時(用戶+內核):ITIMER_PROF → 27)SIGPROF 計算占用cpu及執行系

統調用的時間

信號集操作函數:

內核通過讀取未決信號集來判斷信號是否應被處理。信號屏蔽字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 函數。

9、sigprocmask函數

用來屏蔽信號、解除屏蔽也使用該函數。其本質,讀取或修改進程的信號屏蔽字(PCB

中)

嚴格注意,屏蔽信號:只是將信號處理延后執行(延至解除屏蔽);而忽略表示將信號

丟處理。

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

參數:

set:傳入參數,是一個位圖,set中哪位置1,就表示當前進程屏蔽哪個信號。

oldset:傳出參數,保存舊的信號屏蔽集。

how參數取值:假設當前的信號屏蔽字為mask

SIG_BLOCK: 當how設置為此值,set表示需要屏蔽的信號。相當于 mask = mask|set

SIG_UNBLOCK: 當how設置為此,set表示需要解除屏蔽的信號。相當于 mask = mask & ~set

SIG_SETMASK: 當how設置為此,set表示用于替代原始屏蔽及的新屏蔽集。相當于 mask = set若,調用sigprocmask解除了對當前若干個信號的阻塞,則在sigprocmask返回

前,至少將其中一個信號遞達。

10、sigpending函數

讀取當前進程的未決信號集

int sigpending(sigset_t *set); //set傳出參數。

返回值:成功:0;失敗:-1,設置errno

上一篇:嵌入式學習筆記:linux進程間通信-消息隊列、信號集

下一篇:嵌入式學習筆記:指針函數詳解

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 国产精品资源手机在线播放 | 精品在线一区二区 | 亚洲看片 | 九色综合久久综合欧美97 | 欧美男人的天堂 | 免费a大片| 久久久久免费精品视频 | 日本午夜大片 | 97人洗澡从澡人人爽人人模 | 久草论坛 | 久久一本岛在免费线观看2020 | 91精品久久 | 免费黄色的网站 | 日本免费高清视频 | 免费精品美女久久久久久久久久 | 国产成人亚洲精品2020 | 黄色a级免费网站 | 久热国产视频 | 九九热免费在线视频 | 国产午夜免费视频片夜色 | 欧美三级成人 | 久久是免费只精品热在线 | 极品美女一级毛片免费 | 国产一级做a爰大片免费久久 | 毛片爱做的片 | 男人懂得成a人v网站 | 香港三级日本三级澳门三级人 | 国产精品亚洲二区在线 | 人人做| 男女午夜性爽快免费视频不卡 | 欧美日韩不卡中文字幕在线 | 免费高清在线观看a网站 | 国产成人小视频 | 夭天曰天天躁天天摸在线观看 | 2019av在线视频 | 天天插夜夜操 | 欧美洲精品亚洲精品中文字幕 | 两个人看的www高清免费观看 | 亚洲清色 | 国内福利写真片视频在线观看 | 亚洲天堂成人在线 |