国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送

這篇具有很好參考價(jià)值的文章主要介紹了【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

信號(hào)的舊識(shí)引入

kill -l是一個(gè)在LinuxUnix系統(tǒng)中使用的命令,用于列出可用的信號(hào)列表。

在Linux和Unix系統(tǒng)中,進(jìn)程可以通過發(fā)送信號(hào)來與其他進(jìn)程或操作系統(tǒng)交互。kill 命令可以向指定的進(jìn)程發(fā)送一個(gè)特定的信號(hào),以便對(duì)其進(jìn)行控制,例如終止進(jìn)程或重新啟動(dòng)進(jìn)程等。

kill -l 命令會(huì)列出可用的信號(hào)列表,每個(gè)信號(hào)都有一個(gè)唯一的數(shù)字編號(hào)和一個(gè)名稱。輸出結(jié)果通常是一個(gè)由數(shù)字和名稱組成的列表,例如:

[AMY@VM-12-15-centos ~]$ kill -l
 1) SIGHUP	 	2) SIGINT	 	3) SIGQUIT	 	4) SIGILL	 	5) SIGTRAP
 6) SIGABRT	 	7) SIGBUS	 	8) SIGFPE	 	9) SIGKILL		10) SIGUSR1
11) SIGSEGV		12) SIGUSR2		13) SIGPIPE		14) SIGALRM		15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD		18) SIGCONT		19) SIGSTOP		20) SIGTSTP
21) SIGTTIN		22) SIGTTOU		23) SIGURG		24) SIGXCPU		25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF		28) SIGWINCH	29) SIGIO		30) SIGPWR
31) SIGSYS		34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

我們可以發(fā)現(xiàn)里面數(shù)字沒有0、32 、33:
1~31普通信號(hào)
34~64實(shí)時(shí)信號(hào)

進(jìn)程信號(hào)的認(rèn)識(shí):信號(hào)是給進(jìn)程發(fā)的,比如kill -9 (pid)
信號(hào)相關(guān)總結(jié):

  • 進(jìn)程是如何識(shí)別信號(hào)的?認(rèn)識(shí)+動(dòng)作
  • 進(jìn)程本身是被程序員編寫的屬性和邏輯的集合—程序員編碼完成的
  • 當(dāng)進(jìn)程收到信號(hào)的時(shí)候,進(jìn)程可能正在執(zhí)行更重要的代碼,所以信號(hào)不一定會(huì)被立即處理
  • 進(jìn)程本身必須要有對(duì)于信號(hào)的保存能力
  • 進(jìn)程在處理信號(hào)(信號(hào)被捕捉)的時(shí)候,一般有三種動(dòng)作(默認(rèn),自定義,忽略)

如果一個(gè)信號(hào)是發(fā)給進(jìn)程的,而進(jìn)程要保存,那么應(yīng)該保存在哪里? task struct(PCB)
如何保存呢?是否收到了指定的信號(hào)1~31

struct task_struct
{
	...
	unsigned int signal;
	...
}

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
32位:
比特位的位置,代表信號(hào)編號(hào)。
比特位的內(nèi)容,代表是否收到該信號(hào),0沒有,1有

發(fā)送信號(hào)的本質(zhì):修改PCB中的信號(hào)位圖

PCB是內(nèi)核維護(hù)的數(shù)據(jù)結(jié)構(gòu),PCB的管理者是OS,那么誰有權(quán)力修改PCB的內(nèi)容呢?是OS,所以無論我們學(xué)習(xí)多少種發(fā)送信號(hào)的方法,本質(zhì)上都是通過OS向目標(biāo)進(jìn)程發(fā)送信號(hào)。那么OS一定需要提供發(fā)送信號(hào)的相關(guān)系統(tǒng)調(diào)用,我們也可以推測(cè)出kill命令,底層肯定是調(diào)用了對(duì)應(yīng)的系統(tǒng)調(diào)用


信號(hào)引入

我們常常使用CTRL+c來終止一個(gè)正在運(yùn)行的進(jìn)程,本質(zhì)上,這個(gè)CTRL+c是一個(gè)組合鍵,OS將其解釋成為2號(hào)信號(hào)2) SIGINT

我們可以使用:

man 7 signal

原始POSIX.1-1990標(biāo)準(zhǔn)中描述的信號(hào):
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送

signal調(diào)用

man 2 signal

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
函數(shù)原型:

sighandler_t signal(int signum, sighandler_t handler);

案例使用:

#include <iostream>
#include <unistd.h>
#include <signal.h>

void handler(int signo)
{
    std::cout << "進(jìn)程捕捉到了一個(gè)信號(hào),信號(hào)編號(hào)是: " << signo << std::endl;
}
int main()
{
    // 這里是signal函數(shù)的調(diào)用,并不是handler的調(diào)用
    /// 僅僅是設(shè)置了對(duì)2號(hào)信號(hào)的捕捉方法,并不代表該方法被調(diào)用了
    // 一般這個(gè)方法不會(huì)執(zhí)行,除非收到對(duì)應(yīng)的信號(hào)!
    signal(2, handler);

    while(true)
    {
        std::cout << "我是一個(gè)進(jìn)程: " << getpid() << std::endl;
        sleep(1);
    }
}

直接執(zhí)行我們并沒有執(zhí)行handler(),因?yàn)闆]有傳遞這個(gè)信號(hào)
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
我們?cè)趫?zhí)行的時(shí)候按CTRL+c就會(huì)執(zhí)行handler()
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
為什么我們現(xiàn)在的CTRL+c不能夠終止進(jìn)程呢?是因?yàn)槲覀儗⒛J(rèn)動(dòng)作改為自定義動(dòng)作而去執(zhí)行handler()了,所以我們不能終止,需要終止我們?cè)?code>handler()函數(shù)最后加上exit就行。當(dāng)然我們還可以使用kill -9 (pid)去殺掉這個(gè)進(jìn)程


系統(tǒng)調(diào)用向目標(biāo)進(jìn)程發(fā)送信號(hào)

模擬實(shí)現(xiàn)一個(gè)kill命令

先寫了一個(gè)將來會(huì)一直運(yùn)行的程序mytest.cpp,用來進(jìn)行后續(xù)的命令測(cè)試

#include <iostream>
#include <sys/types.h>
#include <unistd.h>
int main()
{
    while(true)
    {
        std::cout << "我是一個(gè)正在運(yùn)行的進(jìn)程,pid: " << getpid() << std::endl;
        sleep(1);
    }
}

我們使用man手冊(cè)查看kill的系統(tǒng)調(diào)用
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送

然后我們實(shí)現(xiàn)讀取鍵盤部分代碼mysignal.cpp

#include <iostream>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
using namespace std;

static void Usage(const string &proc)
{
    std::cout << "\nUsage: " << proc << " pid signo\n" << std::endl;
}
int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }
    pid_t pid = atoi(argv[1]);
    int signo = atoi(argv[2]);
    int n = kill(pid,signo);
    if(n != 0)
    {
        perror("kill");
    }
    return 0;
}

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
從上述過程我們可得:我們使用自己的調(diào)用實(shí)現(xiàn)了kill命令,我們平時(shí)使用的kill命令其實(shí)也就是封裝的系統(tǒng)調(diào)用kill

kill()可以向任意進(jìn)程發(fā)送任意信號(hào)

raise給自己發(fā)送任意信號(hào)

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送

int main(int argc, char* argv[])
{
    int cnt=0;
    while(true)
    {
        cnt++;
        cout<<"cnt:"<<cnt<<endl;
        if(cnt>=3)
        {
            raise(9);
        }
    }
    return 0;
}

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
函數(shù)原型:

int raise(int sig);

只需要傳入信號(hào)值,就可以直接發(fā)送該信號(hào)

abort給自己發(fā)送指定信號(hào)(6)SIGABRT

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送

int cnt=0;
while(true)
{
    cnt++;
    cout<<"cnt:"<<cnt<<endl;
    if(cnt>=3)
    {
        abort();
        //raise(9);
    }
}

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
前三個(gè)調(diào)用總結(jié):

  • kill()可以想任意進(jìn)程發(fā)送任意信號(hào)
  • raise()給自己 發(fā)送 任意信號(hào) 等同:kill(getpid(), 任意信號(hào))
  • abort()給自己 發(fā)送 指定的信號(hào)SIGABRT 等同:kill(getpid(), SIGABRT)

關(guān)于信號(hào)處理的行為的理解:有很多的情況,進(jìn)程收到大部分的信號(hào),默認(rèn)處理動(dòng)作都是終止進(jìn)程
信號(hào)的意義:信號(hào)的不同,代表不同的事件,但是對(duì)事件發(fā)生之后的處理動(dòng)作可以一樣!


硬件異常產(chǎn)生信號(hào)

除0異常

我們對(duì)一個(gè)常數(shù)進(jìn)行除0運(yùn)算:
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
我們捕捉這個(gè)信號(hào):

void catchSig(int signo)
{
    std::cout << "獲取到一個(gè)信號(hào),信號(hào)編號(hào)是: " << signo << std::endl;
}
int main(int argc, char* argv[])
{

    signal(SIGFPE, catchSig);
    while (true)
    {
        std::cout << "我在運(yùn)行中...." << std::endl;
        sleep(1);
        int a = 10;
        a /= 0;
    }
    return 0;
}

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
雖然我們將signal(SIGFPE, catchSig);是寫在循環(huán)之前,但是當(dāng)我們進(jìn)行除0以后,它還是會(huì)運(yùn)行,這是因?yàn)椋?code>signal()在這里是注冊(cè)一種未來的方法,當(dāng)某種條件成立后就自動(dòng)調(diào)用這個(gè)注冊(cè)好的方法

我們還發(fā)現(xiàn)這個(gè)捕捉到信號(hào)SIGFPE后,它就一直運(yùn)行catchSig()打印
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
除0異常解釋:
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送

由上述輸出結(jié)果我們可以知道:收到信號(hào)不一定會(huì)引起進(jìn)程退出,沒有退出有可能還會(huì)被調(diào)度。而CPU內(nèi)部的寄存器只有一份,但是寄存器里面的內(nèi)容,屬于當(dāng)前進(jìn)程上下文。一旦出現(xiàn)異常,我們有沒有能力或者動(dòng)作去修正這個(gè)問題呢?答案是沒有,比如溢出標(biāo)記位被置1了,我們有沒有能力去更改為0呢?我們肯定不能,因?yàn)闋顟B(tài)寄存器是由CPU自己維護(hù)的,用戶沒有辦法也沒有權(quán)力去更改。

當(dāng)進(jìn)程被切換的時(shí)候,就有無數(shù)次狀態(tài)寄存器被保存和恢復(fù)的過程,所以每一次恢復(fù)的時(shí)候,就讓OS識(shí)別到了CPU內(nèi)部的狀態(tài)寄存器中的溢出標(biāo)志位是1

野指針訪問異常

while(true)
{
    std::cout << "我在運(yùn)行中...." << std::endl;
    sleep(1);
    int *p = nullptr;
    *p=10;
}

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送

void catchSig(int signo)
{
    std::cout << "獲取到一個(gè)信號(hào),信號(hào)編號(hào)是: " << signo << std::endl;
}
int main(int argc, char *argv[])
{

    signal(11, catchSig);

    int *p = nullptr;
    *p = 10;
    while (true)
    {
        std::cout << "我在運(yùn)行中...." << std::endl;
        sleep(1);
    }
    return 0;
}

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
由上述的操作結(jié)果我們可知:野指針訪問屬于是(11) SIGSEGV,且跟除0的捕捉結(jié)果是一樣的,也是一直調(diào)用catchSig()。
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
MMU位于CPU內(nèi)部,在ARM32中,MMU主要完成虛擬地址到物理地址的映射,并且能夠控制內(nèi)存的訪問權(quán)限,而頁表是實(shí)現(xiàn)上述功能的主要手段。頁表又分為一級(jí)頁表、二級(jí)頁表,在ARM64中甚至還有三級(jí)頁表。上圖這樣畫只是為了更形象。

while循環(huán)的代碼不會(huì)被使用因?yàn)椋涸L問野指針并觸發(fā)SIGSEGV信號(hào)時(shí),程序已經(jīng)進(jìn)入了異常狀態(tài)。當(dāng)catchSig函數(shù)被調(diào)用時(shí),異常狀態(tài)并沒有被完全處理,因此程序進(jìn)入了一個(gè)不穩(wěn)定的狀態(tài)。一旦catchSig函數(shù)返回,程序會(huì)嘗試?yán)^續(xù)執(zhí)行之前的指令,但由于進(jìn)程仍處于異常狀態(tài),又會(huì)再次觸發(fā)SIGSEGV信號(hào)。這將導(dǎo)致catchSig函數(shù)被不斷地調(diào)用。


軟件條件產(chǎn)生信號(hào)

管道通信舉例:
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
當(dāng)讀端關(guān)閉,寫端卻一直在寫的情況時(shí)候,OS會(huì)發(fā)送(13) SIGPIPE信號(hào)來讓寫端關(guān)閉,這中情況就是由軟件條件觸發(fā)產(chǎn)生信號(hào)。

定時(shí)器軟件條件:
alarm():設(shè)定鬧鐘
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送

int main(int argc, char *argv[])
{
    alarm(1);
    int cnt = 0;
    while (true)
    {
        cout << "cnt:" << cnt << endl;
        cnt++;
    }
    return 0;
}

輸出結(jié)果:
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
我們更改一下代碼:

int cnt = 0;
void catchSig(int signo)
{
    std::cout << "獲取到一個(gè)信號(hào),信號(hào)編號(hào)是: " << signo << "  cnt:" << cnt << std::endl;
}
int main(int argc, char *argv[])
{
    signal(SIGALRM, catchSig);
    alarm(1);
    while (true)
    {
        cnt++;
    }

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
我們首先可以的個(gè)結(jié)論:IO確實(shí)很慢,都是1秒鐘,一直打印cnt的那個(gè)明顯累加次數(shù)很少(我使用的是云服務(wù)器,這些運(yùn)行的結(jié)果還要通過網(wǎng)絡(luò)傳遞給我,所以會(huì)更慢,一般使用虛擬機(jī)會(huì)快很多)

我們這里跟之前的輸出結(jié)果不一樣,這里只打印了一次,說明alarm只發(fā)送一次信號(hào)

拓展

為什么你說設(shè)置“鬧鐘”是軟件條件呢?
任意一個(gè)進(jìn)程,都可以通過alarm系統(tǒng)調(diào)用在內(nèi)核中設(shè)置鬧鐘,OS內(nèi)可能會(huì)存在著很多的鬧鐘,那么操作系統(tǒng)要不要管理這些鬧鐘呢?要→先描述再組織

舉例:操作系統(tǒng)中有很多管理鬧鐘的方法比如堆等
描述:

struct alarm
{
    uint64_t when; // 未來的超時(shí)時(shí)間int type
    // 鬧鐘類型,一次性的,還是周期性
    task_struct *p;
    struct alarm *next;
}

組織:
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
OS會(huì)周期性的檢測(cè)這些鬧鐘,如果curr_timestamp > alarm.when,超時(shí)了OS發(fā)送SIGALARM -> alarm.p;


總結(jié)思考

關(guān)于信號(hào)發(fā)送的問題:

  • 上面所說的所有信號(hào)產(chǎn)生,最終都要有OS來進(jìn)行執(zhí)行,為什么?
    OS是進(jìn)程的管理者,也只有OS有權(quán)利去操作

  • 信號(hào)的處理是否是立即處理的?
    在合適的時(shí)候

  • 信號(hào)如果不是被立即處理,那么信號(hào)是否需要暫時(shí)被進(jìn)程記錄下來?記錄在哪里最合適呢?
    是的,保存在PCB

  • 一個(gè)進(jìn)程在沒有收到信號(hào)的時(shí)候,能否能知道,自己應(yīng)該對(duì)合法信號(hào)作何處理呢?
    我們應(yīng)該知道,比如紅燈快要亮起,但還沒有,此時(shí)我們知不知道紅燈亮起的時(shí)候該怎么辦?答案是知道。信號(hào)還沒有產(chǎn)生但是我們應(yīng)該知道信號(hào)產(chǎn)生該做什么處理,這個(gè)工作由程序員系統(tǒng)中代碼默認(rèn)體現(xiàn)。

  • 如何理解OS向進(jìn)程發(fā)送信號(hào)?能否描述一下完整的發(fā)送處理過程?
    就是OS直接修改目標(biāo)進(jìn)程中PCB存放信號(hào)的位圖

進(jìn)程退出時(shí)核心轉(zhuǎn)儲(chǔ)問題

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
同樣都是越界,為什么右邊的越界報(bào)錯(cuò)了?因?yàn)閿?shù)組是只分配了10的空間,但是不代表整個(gè)函數(shù)的棧幀結(jié)構(gòu)只有那么多,所以你即使越界了,但是你還是在有效棧區(qū)里所以就沒報(bào)錯(cuò),除非你訪問了一個(gè)完全不屬于你的空間,比如系統(tǒng)的某些空間,這時(shí)候OS就會(huì)識(shí)別出來。(不同編譯器檢查越界方式也可能不同,比如vs2019就是采用抽檢)

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送

Term正常結(jié)束,Core除了終止還要做其他工作

在云服務(wù)器上,默認(rèn)如果進(jìn)程是core退出的,我們暫時(shí)看不到明顯的現(xiàn)象,如果想看到:

[AMY@VM-12-15-centos lesson_18]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7260
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 100001
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7260
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

云服務(wù)器默認(rèn)關(guān)閉了core file size選項(xiàng):
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
如何打開這個(gè)選項(xiàng)呢?
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
我們現(xiàn)在還多了一個(gè)文件core.15199
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
(core dumped)核心轉(zhuǎn)儲(chǔ)︰當(dāng)進(jìn)程出現(xiàn)異常的時(shí)候,我們將進(jìn)程在對(duì)應(yīng)的時(shí)刻,在內(nèi)存中的有效數(shù)據(jù),轉(zhuǎn)儲(chǔ)到磁盤中–核心轉(zhuǎn)儲(chǔ)!而core.1519915199是引起core問題的進(jìn)程的pid

進(jìn)程在運(yùn)行時(shí)出異常,以前的終止就是直接結(jié)束,而現(xiàn)在打開了core選項(xiàng)進(jìn)程在終止時(shí)會(huì)多做一個(gè)工作,就是把進(jìn)程中一些有效的二進(jìn)制數(shù)據(jù)給dumped轉(zhuǎn)儲(chǔ)到磁盤當(dāng)中,這個(gè)就叫核心轉(zhuǎn)儲(chǔ),形成的這個(gè)臨時(shí)文件以core命名,后綴為該進(jìn)程的pid

為什么要有這個(gè)呢?
正常我們程序崩潰了,我們最想知道的是為什么崩潰?在哪里崩潰?而核心轉(zhuǎn)儲(chǔ)可方便我們調(diào)試(Linux調(diào)試我們需要帶上 -g選項(xiàng))
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
gdb上下文之中,輸入core-file core.(pid值)

Term不可以核心轉(zhuǎn)儲(chǔ),Core可以核心轉(zhuǎn)儲(chǔ)


小實(shí)驗(yàn)

如果我們將所有的信號(hào)全部捕捉,那么還能不能殺死這個(gè)進(jìn)程呢?

void catchSig(int signo)
{
    std::cout << "獲取到一個(gè)信號(hào),信號(hào)編號(hào)是: " << signo << std::endl;
}
int main(int argc, char *argv[])
{
    for(int signo = 1; signo <= 31; signo++)
    {
        signal(signo, catchSig);
    }
    while(true) 
    {
        cout << "我在運(yùn)行: " << getpid() <<endl;
        sleep(3);
    }
    return 0;
}

【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送,Linux基礎(chǔ),linux,運(yùn)維,服務(wù)器,信號(hào)產(chǎn)生,信號(hào)發(fā)送
我們將所有信號(hào)全部捕捉,別的確實(shí)無法終止進(jìn)程,但是kill -9可以,這也是OS的設(shè)置,OS禁止捕捉9號(hào)進(jìn)程,即使你捕捉了也無法生效,它是管理員進(jìn)程。否則如果真出現(xiàn)惡意程序捕捉所有信號(hào),那豈不是真不能終止。


如有錯(cuò)誤或者不清楚的地方歡迎私信或者評(píng)論指出????文章來源地址http://www.zghlxwxcb.cn/news/detail-578395.html

到了這里,關(guān)于【Linux】進(jìn)程信號(hào) -- 信號(hào)產(chǎn)生 | 系統(tǒng)調(diào)用、硬件、軟件的信號(hào)發(fā)送的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Linux】進(jìn)程信號(hào)——進(jìn)程信號(hào)的概念和介紹、產(chǎn)生信號(hào)、四種產(chǎn)生信號(hào)方式、阻塞信號(hào)、捕捉信號(hào)、阻塞和捕捉信號(hào)的函數(shù)

    【Linux】進(jìn)程信號(hào)——進(jìn)程信號(hào)的概念和介紹、產(chǎn)生信號(hào)、四種產(chǎn)生信號(hào)方式、阻塞信號(hào)、捕捉信號(hào)、阻塞和捕捉信號(hào)的函數(shù)

    ??在Linux中,進(jìn)程信號(hào)是一種異步的事件通知機(jī)制,用于通知進(jìn)程某個(gè)事件已經(jīng)發(fā)生。它是進(jìn)程間通信的一種方式,可以用來控制進(jìn)程的行為。 ??當(dāng)一個(gè)進(jìn)程收到信號(hào)時(shí),操作系統(tǒng)會(huì)中斷該進(jìn)程的正??刂屏鞒蹋?zhí)行相應(yīng)的處理函數(shù)。進(jìn)程收到信號(hào)后有三種處理方式:

    2024年02月02日
    瀏覽(26)
  • 【Linux】進(jìn)程信號(hào)概念 | 核心轉(zhuǎn)儲(chǔ) | 信號(hào)的產(chǎn)生

    【Linux】進(jìn)程信號(hào)概念 | 核心轉(zhuǎn)儲(chǔ) | 信號(hào)的產(chǎn)生

    進(jìn)程信號(hào)重點(diǎn): 1.掌握Linux信號(hào)的基本概念 2.掌握信號(hào)產(chǎn)生的一般方式 3.理解信號(hào)遞達(dá)和阻塞的概念,原理。 4.掌握信號(hào)捕捉的一般方式。 5.重新了解可重入函數(shù)的概念。 6.了解競(jìng)態(tài)條件的情景和處理方式 7.了解SIGCHLD信號(hào), 重新編寫信號(hào)處理函數(shù)的一般處理機(jī)制 學(xué)習(xí)的順序

    2024年02月22日
    瀏覽(24)
  • Linux入門之進(jìn)程信號(hào)|信號(hào)產(chǎn)生的方式

    Linux入門之進(jìn)程信號(hào)|信號(hào)產(chǎn)生的方式

    文章目錄 一、信號(hào)入門 1.linux信號(hào)的基本概念 2.使用kill -l 命令可以查看系統(tǒng)定義的信號(hào)列表 3.信號(hào)處理常見方式 二、產(chǎn)生信號(hào) 1.通過終端按鍵產(chǎn)生信號(hào) 2.通過調(diào)用系統(tǒng)函數(shù)向進(jìn)程發(fā)信號(hào) 3.由軟條件產(chǎn)生信號(hào) 4.硬件異常產(chǎn)生信號(hào) ??? 1. /0異常 ??? 2.模擬野指針 信號(hào)是進(jìn)程之

    2024年02月09日
    瀏覽(20)
  • 【Linux】第八講:Linux進(jìn)程信號(hào)詳解(一)_ 認(rèn)識(shí)信號(hào) | 產(chǎn)生信號(hào)

    【Linux】第八講:Linux進(jìn)程信號(hào)詳解(一)_ 認(rèn)識(shí)信號(hào) | 產(chǎn)生信號(hào)

    「前言」文章是關(guān)于Linux進(jìn)程信號(hào)方面的知識(shí),本文的內(nèi)容是Linux進(jìn)程信號(hào)第一講,講解會(huì)比較細(xì),下面開始! 「歸屬專欄」Linux系統(tǒng)編程 「主頁鏈接」個(gè)人主頁 「筆者」楓葉先生(fy) ?「楓葉先生有點(diǎn)文青病」「每篇一句」? 人生天地間,忽如遠(yuǎn)行客。 ——《樂府·青青陵上

    2023年04月25日
    瀏覽(23)
  • 【Linux】進(jìn)程信號(hào) --- 信號(hào)的產(chǎn)生 保存 捕捉遞達(dá)

    【Linux】進(jìn)程信號(hào) --- 信號(hào)的產(chǎn)生 保存 捕捉遞達(dá)

    被愛情困住的是傻子 1. 關(guān)于信號(hào)這個(gè)話題我們其實(shí)并不陌生,早在以前的時(shí)候,我們想要?dú)⑺滥硞€(gè)后臺(tái)進(jìn)程的時(shí)候,無法通過ctrl+c熱鍵終止進(jìn)程時(shí),我們就會(huì)通過kill -9的命令來殺死信號(hào)。 查看信號(hào)也比較簡(jiǎn)單,通過kill -l命令就可以查看信號(hào)的種類,雖然最大的信號(hào)編號(hào)是

    2023年04月23日
    瀏覽(20)
  • 【Linux】進(jìn)程信號(hào)(完整版) --- 信號(hào)產(chǎn)生 信號(hào)保存 信號(hào)捕捉 可重入函數(shù) volatile SIGCHLD信號(hào)等

    【Linux】進(jìn)程信號(hào)(完整版) --- 信號(hào)產(chǎn)生 信號(hào)保存 信號(hào)捕捉 可重入函數(shù) volatile SIGCHLD信號(hào)等

    ?? 作者: 阿潤菜菜 ?? 專欄: Linux系統(tǒng)編程 我們想要?dú)⑺滥硞€(gè)后臺(tái)進(jìn)程的時(shí)候,無法通過ctrl+c熱鍵終止進(jìn)程時(shí),我們就會(huì)通過kill -9的命令來殺死信號(hào)。 查看信號(hào)也比較簡(jiǎn)單,通過 kill -l 命令就可以查看所有信號(hào)的種類,雖然最大的信號(hào)編號(hào)是64,但實(shí)際上所有信號(hào)只有6

    2024年02月04日
    瀏覽(26)
  • 【Linux】進(jìn)程信號(hào)篇Ⅰ:信號(hào)的產(chǎn)生(signal、kill、raise、abort、alarm)、信號(hào)的保存(core dump)

    【Linux】進(jìn)程信號(hào)篇Ⅰ:信號(hào)的產(chǎn)生(signal、kill、raise、abort、alarm)、信號(hào)的保存(core dump)

    kill -l 可以查看所有信號(hào): 其中,前面的數(shù)字就是信號(hào),后面的大寫英文就是信號(hào)名稱,實(shí)際就是宏。 我們需要關(guān)注的是 1~31 號(hào)普通信號(hào),關(guān)注他們有沒有產(chǎn)生(可以用 0 或者 1 表示)。 所以,進(jìn)程的 pcb 中,需要對(duì)產(chǎn)生的信號(hào)先用 位圖 保存起來,再按照一定的順序去處理

    2024年01月25日
    瀏覽(31)
  • Linux——進(jìn)程信號(hào)的發(fā)送

    Linux——進(jìn)程信號(hào)的發(fā)送

    目錄 一.信號(hào)發(fā)送的概念 首先來講幾個(gè)發(fā)送術(shù)語: 它有三種情況: ?注意: 二.信號(hào)在內(nèi)核中的表示示意圖 三.信號(hào)捕捉 ?所以總結(jié)一下: 此時(shí),會(huì)出現(xiàn)這樣一個(gè)疑問:操作系統(tǒng)是如何得知現(xiàn)在被執(zhí)行的進(jìn)程是用戶態(tài)還是內(nèi)核態(tài)? 問題2:CPU在執(zhí)行某個(gè)進(jìn)程時(shí)是如何跑到操作

    2024年02月13日
    瀏覽(22)
  • Linux操作系統(tǒng)——第五章 進(jìn)程信號(hào)

    Linux操作系統(tǒng)——第五章 進(jìn)程信號(hào)

    ? ? ? 目錄 信號(hào)概念 用kill -l命令可以察看系統(tǒng)定義的信號(hào)列表 信號(hào)處理常見方式概覽 產(chǎn)生信號(hào) 1. 通過終端按鍵產(chǎn)生信號(hào) 2. 調(diào)用系統(tǒng)函數(shù)向進(jìn)程發(fā)信號(hào) 3. 由軟件條件產(chǎn)生信號(hào) 4. 硬件異常產(chǎn)生信號(hào) 阻塞信號(hào) 1. 信號(hào)其他相關(guān)常見概念 2. 在內(nèi)核中的表示 3. sigset_t 4. 信號(hào)集操作

    2024年02月11日
    瀏覽(24)
  • 【linux】信號(hào)——信號(hào)產(chǎn)生

    【linux】信號(hào)——信號(hào)產(chǎn)生

    自我名言 : 只有努力,才能追逐夢(mèng)想,只有努力,才不會(huì)欺騙自己。 喜歡的點(diǎn)贊,收藏,關(guān)注一下把! 首先說明一點(diǎn)信號(hào)不是信號(hào)量。不能把這兩個(gè)東西放在一起。 那信號(hào)講什么呢? 那信號(hào)是怎么回事,這里只能這樣說, 信號(hào)是針對(duì)進(jìn)行發(fā)送某種信號(hào)到來的一種機(jī)制,讓

    2024年02月05日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包