一、訊號
訊號用來通知進程發生了非同步事件。核心也可以因為內部事件而向進程發送訊號,通知進程發生了某個事件。請注意,訊號只是用來通知某個進程發生了什麼事件,並不會給該進程傳遞任何資料。
**用kill-l 命令查看系統定義的信號列表
二、信號的產生方式
① 透過鍵盤組合鍵向前台發送信號,(一個命令後面加& 可以發到後台運行)
a.訊號的預設動作是終止進程,SIGQUIT的預設處理動作是終止進程並且Core Dump,(core dump是進程異常終止時,可以選擇把進程的用戶空間記憶體資料全部保存到磁碟上,檔案名稱通常是core,這就叫做core dump,通常就是程式有了BUG,可以用調試器檢查core檔案以查清錯誤原因,)預設是不允許產生core檔案的,因為core檔案中可能包含使用者密碼,不安全,在開發調試時可以用ulimit指令改變這個限制,允許產生core檔。
用命令ulimit -c 1024
ulimit命令改變了Shell進程的Resource Limit,test進程的PCB由Shell進程複製而來,所以也具有和Shell進程相同的Resource Limit值,這樣就可以產生Core Dump了
② 透過呼叫系統函數想進程發送訊號
a.kill指令是呼叫kill函數來實現的。 kill函數可以給一個指定的程序發送指定的信號.raise函數可以給當前程序發送指定的信號(自己給自己發信號).
int kill(pid_t pid, int signo);
int raise(int signo);
都是成功回傳0,錯誤回傳-1;
abort函數使目前程序接收到SIGABRT訊號而異常終止。
void abort(void);
像exit函數一樣,abort函數總是會成功的,所以沒有回傳值。
③ 由軟體條件產生的訊號
a.alarm函數與SIGALRM訊號
unsigned int alarm(unsigned int seconds);呼叫alarm函式可以設定一個鬧鐘,就是告訴核心在senconds秒後給目前行程發送SIGALRM ,預設動作是終止目前進程,函數的回傳值是0或是以前設定的鬧鐘時間還餘下的秒數。
三、處理訊號的方式
① 忽略此訊號
② 執行訊號的預設處理動作,一般是終止進程
③ 捕捉訊號
四、訊號的遞達與阻塞
③ 捕捉訊號
四、訊號的遞達與阻塞
①、阻斷的處理動作稱為訊號遞達(Delivery),訊號從產生到遞達之間的狀態,稱為訊號未決(Pending)。進程可以選擇阻塞(Block )某個訊號。被阻塞的訊號產生時將保持在未決狀態,直到進程解除對此訊號的阻塞,才執行遞達的動作。阻塞和忽略是不一樣的只要訊號被阻塞就不會遞達,而忽略是在遞達之後可選的一種處理動作。
每個訊號都有兩個標誌位分別表示阻塞(block)和未決(pending),還有一個函數指標表示處理動作。訊號產生時,核心在進程控制區塊中設定該訊號的未決標誌,直到訊號遞達才清除該標誌
如果在進程解除對某訊號的阻塞之前這種訊號產生過多次,在Linux中常規訊號在遞達之前產生多次只計一次,而即時訊號在遞達之前產生多次可以依序放在一個佇列裡。每個訊號只有一 個bit的未決標誌,非0即1,不記錄該訊號產生了多少次,阻塞標誌也是這樣表示的。 (blank是一種狀態,pending表示的是有無)未決和阻塞標誌可以用相同的資料型態sigset_t來儲存,sigset_t稱為訊號集,阻斷訊號集也叫做目前行程的訊號屏蔽字(Signal Mask) ,這裡的「屏蔽」應該被理解為阻塞而不是忽略。
#include <signal.h> int sigemptyset(sigset_t *set);//初始化对应的信号集bit位为0 int sigfillset(sigset_t *set);//初始化对象的信号集bit位为1 int sigaddset(sigset_t *set, int signo);//添加有效信号 int sigdelset(sigset_t *set, int signo);//删除有效信号 int sigismember(const sigset_t *set, int signo);//判断一个信号集的有效信号中是否包含某种信号,包含返回1,不包含返回0。
③、sigprocmask
呼叫函數sigprocmask可以讀取或更改進程的訊號屏蔽字(阻塞訊號集)。
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);成功則為0,出錯則為-1;
如果調用sigprocmask解除了對當前若干個未決信號的阻塞,則在sigprocmaskask返回前,至少將其中一個信號遞達.
how參數的含義
SIG_BLOCK set包含了我們希望添加到當前信號屏蔽字的信號,
SIG_UNBLOCK set包含了我們希望從當前信號屏蔽在字中解除阻塞的信號,
SIG_SETMASK 設定目前訊號屏蔽字為set所指向的值,
④、sigpending
int sigpending(sigset_t *set);
sigpending讀取目前進程的未決訊號集,透過set參數傳出。呼叫成功則回傳0,出錯則回傳-1。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~用程序說明
#include<stdio.h> 2 #include<unistd.h> 3 #include<signal.h> 4 void printsigset(sigset_t* sig) 5 { 6 int i=0; 7 for(;i<31;i++) 8 { 9 if(sigismember(sig,i))//判断指定信号是否在目标集合中 10 { 11 printf("1"); 12 } 13 else 14 { 15 printf("0"); 16 } 17 } 18 printf("\n"); 19 } 20 int main() 21 { 22 sigset_t s,p;//定义信号集 23 sigemptyset(&s);//初始化 24 sigemptyset(&p); 25 sigaddset(&s,SIGINT);//设置信号ctrl+C 26 sigprocmask(SIG_BLOCK,&s,NULL);//设置阻塞信号集,阻塞 SIGINT信号 27 while(1) 28 { 29 sigpending(&p);//获取未决信号集 30 printsigset(&p); 31 sleep(1); 32 } 33 return 0; 34 }

结果分析:
程序运行时,每秒钟把各信号的未决状态打印一遍,直到按Ctrl-C将会使SIGINT信号处于未决状态,
五、捕捉信号
a.内核如何实现信号的捕捉
如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号,处理过程如下,举例来说明
1. 用户程序注册了SIGQUIT信号的处理函数sighandler。
2. 当前正在执行main函数,这时发生中断或异常切换到内核态。
3. 在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达。
4. 内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函 数,sighandler和main函数使用不同的堆栈空间,它们之间不存在调用和被调用的关系,是两个独立的控制流程。
5. sighandler函数返回后自动执行特殊的系统调用sigreturn再次进入内核态。
6. 如果没有新的信号要递达,这次再返回用户态就是恢复main函数的上下文继续执行了
**(先从用户态―>内核态->返回用户态之前检查有信号递达,返回用户态处理信号->处理完成后再进入内核态->如果没有新的信号递达,返回用户态恢复上下文继续执行)
b.sigaction
int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);
sigaction函数可以读取和修改与指定信号相关联的处理动作。调用成功则返回0,出错则返回- 1
将sa_handler赋值为常数SIG_IGN传给sigaction表示忽略信号,赋值为常数SIG_DFL表示执行系统默认动作,赋值为一个函数指针表示用自定义函数捕捉信号,或者说向内核注册了一个信号处理函 数,该函数返回值为void,可以带一个int参数,通过参数可以得知当前信号的编号,这样就可以用同一个函数处理多种信号。显然,这也是一个回调函数,不是被main函数调用,而是被系统所调用。
当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字,这样就保证了在处理某个信号时,如果这种信号再次产生,那么它会被阻塞到当前处理结束为止。
如果在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字。
c.pause
int pause(void);
pause函数使调用进程挂起直到有信号递达。如果信号的处理动作是终止进程,则进程终止,pause函数没有机会返回;如果信号的处理动作是忽略,则进程继续处于挂起状态,pause不返回;如果信号的处理动作是捕捉,则调用了信号处理函数之后pause返回-1,
用alarm和pause实现sleep(3)的函数
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<signal.h> 4 void sig_alarm(int signo) 5 { 6 //do nothing 7 } 8 unsigned int my_sleep(unsigned int times) 9 { 10 struct sigaction new ,old; 11 unsigned int unslept=0; 12 new.sa_handler=sig_alarm; 13 sigemptyset(&new.sa_mask); 14 sigemptyset(&old.sa_mask); 15 new.sa_flags=0; 16 sigaction(SIGALRM,&new,&old);//注册信号处理函数 17 alarm(times); //设置闹钟 18 pause(); 19 unslept=alarm(0);//取消闹钟 20 sigaction(SIGALRM,&old,NULL);//恢复默认信号处理动作 21 return unslept; 22 } 23 int main() 24 { 25 while(1) 26 { 27 my_sleep(5); 28 printf("5 senconds pass\n"); 29 } 30 return 0; 31 }
六、可重入函数
当捕捉到信号时,不论进程的主控制流程当前执行到哪儿,都会先跳到信号处理函数中执行,从信号处理函数返回后再继续执行主控制流程。信号处理函数是一个单独的控制流程,因为它和主控制流程是异步的,二者不存在调用和被调用的关系,并且使用不同的堆栈空间。引入了信号处理函数使得一个进程具有多个控制流程,如果这些控制流程访问相同的全局资源(全局变量、硬件资源等),就有可能出现冲突。
以上就是Linux--信号的内容,更多相关内容请关注PHP中文网(www.php.cn)!

aphpdepentioncontiveContainerIsatoolThatManagesClassDeptions,增強codemodocultion,可驗證性和Maintainability.itactsasaceCentralHubForeatingingIndections,因此reducingTightCightTightCoupOulplingIndeSingantInting。

選擇DependencyInjection(DI)用於大型應用,ServiceLocator適合小型項目或原型。 1)DI通過構造函數注入依賴,提高代碼的測試性和模塊化。 2)ServiceLocator通過中心註冊獲取服務,方便但可能導致代碼耦合度增加。

phpapplicationscanbeoptimizedForsPeedAndeffificeby:1)啟用cacheInphp.ini,2)使用preparedStatatementSwithPdoforDatabasequesies,3)3)替換loopswitharray_filtaray_filteraray_maparray_mapfordataprocrocessing,4)conformentnginxasaseproxy,5)

phpemailvalidation invoLvesthreesteps:1)格式化進行regulareXpressecthemailFormat; 2)dnsvalidationtoshethedomainhasavalidmxrecord; 3)

tomakephpapplicationsfaster,關注台詞:1)useopcodeCachingLikeLikeLikeLikeLikePachetoStorePreciledScompiledScriptbyTecode.2)MinimimiedAtabaseSqueriSegrieSqueriSegeriSybysequeryCachingandeffeftExting.3)Leveragephp7 leveragephp7 leveragephp7 leveragephpphp7功能forbettercodeefficy.4)

到ImprovephPapplicationspeed,關注台詞:1)啟用opcodeCachingwithapCutoredUcescriptexecutiontime.2)實現databasequerycachingingusingpdotominiminimizedatabasehits.3)usehttp/2tomultiplexrequlexrequestsandreduceconnection.4 limitesclection.4.4

依赖注入(DI)通过显式传递依赖关系,显著提升了PHP代码的可测试性。1)DI解耦类与具体实现,使测试和维护更灵活。2)三种类型中,构造函数注入明确表达依赖,保持状态一致。3)使用DI容器管理复杂依赖,提升代码质量和开发效率。

DatabasequeryoptimizationinPHPinvolvesseveralstrategiestoenhanceperformance.1)Selectonlynecessarycolumnstoreducedatatransfer.2)Useindexingtospeedupdataretrieval.3)Implementquerycachingtostoreresultsoffrequentqueries.4)Utilizepreparedstatementsforeffi


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Dreamweaver CS6
視覺化網頁開發工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

SublimeText3漢化版
中文版,非常好用

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。