主頁 >  其他 > 【Linux】一篇文章搞定 行程間通信 之 信號機制

【Linux】一篇文章搞定 行程間通信 之 信號機制

2021-01-06 12:24:31 其他

信號

  • 1. 信號的概念
  • 2. 信號的產生
    • 2.1 硬體產生的信號
      • 2.3.1 終止行程組合鍵 **ctrl + c**
      • 2.3.2 暫停行程組合鍵 ctrl + z
      • 2.3.3 產生核心轉儲檔案組合鍵 ctrl + |
        • 2.3.3.1 核心轉儲
        • 2.3.3.2 core file size設定
        • 2.3.3.3 使用gdb除錯核心轉儲檔案
        • 2.3.3.4 一些非法行為對應產生的信號量
    • 2.3 軟體產生的信號
      • 2.3.1 kill
        • 2.3.1.1 kill函式
        • 2.3.1.2 kill命令
      • 2.3.2 abort
        • 2.3.2.1 abort函式
  • 3. 信號的注冊
    • 3.1 行程中的未決信號集(位圖)
      • 3.1.1 圖解行程與未決信號集的關系
    • 3.2 非可靠信號注冊
    • 3.3 可靠信號注冊
    • 3.4 sigqueue原始碼
  • 4. 信號的注銷
    • 4.1 非可靠信號的注銷
    • 4.2 可靠信號的注銷
  • 5. 信號的捕捉后的處理方式
    • 5.1 默認處理方式SIG_DFL
    • 5.2 忽略處理方式SIG_IGN
    • 5.3 自定義信號處理方式
      • 5.3.1 signal函式
        • 5.3.1.1 signal函式演示程式
      • 5.3.2 sigaciotn函式
        • 5.3.2.1 sigaction結構體詳解
        • 5.3.2.2 sigaction函式程式演示
        • 5.3.2.3 內核原始碼中的sigaction結構體原始碼
      • 5.3.3 signal函式與sigaction函式的關系
  • 6. 探究回呼函式機制的原始碼定義
    • 6.1 從task_struct到回呼函式handler的結構體嵌套原始碼
    • 6.1 圖解結構體嵌套關系
    • 6.2 原始碼中__sighandler_t的決議
  • 7. 信號的捕捉流程
  • 8. 信號阻塞
    • 8.1 信號阻塞概念及內核原始碼定義
    • 8.2 設定阻塞位圖函式
      • 8.2.1 程式演示

1. 信號的概念

信號的概念理解:

  • 信號是一個程式中斷

信號的種類:使用Kill -l 命令可以查看有多少個信號

[gongruiyang@localhost TestSignal]$ 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
  • 1 至 31 是 非可靠信號
  • 34 至 64 是 可靠信號
  • 非可靠信號 : 當前信號有可能丟失的,丟失就無法執行該信號
  • 可靠信號:當前信號不可能會丟失

查看信號的具體含義命令:

man 7 signal

在這里插入圖片描述

2. 信號的產生

2.1 硬體產生的信號

#include <stdio.h>
#include <unistd.h>

int main()
{

  while(1)
  {
    printf("while回圈ing\n");  
    sleep(1);
  }

  return 0;
}

2.3.1 終止行程組合鍵 ctrl + c

while回圈ing
while回圈ing
while回圈ing
while回圈ing
while回圈ing
^C
  • 在程式運行程序中我們按下 ctrl + c 就可以中斷行程運行
  • 組合鍵ctrl + c 本質上是SIGINT 信號(2號信號),是一個終止信號,終止正在進行的這個前臺行程,該組合鍵對后臺行程沒有任何作用

2.3.2 暫停行程組合鍵 ctrl + z

[gongruiyang@localhost signalCreate]$ ./hardTestExe 
while回圈ing
while回圈ing
while回圈ing
while回圈ing
^Z
[1]+  Stopped               ./hardTestExe
[gongruiyang@localhost signalCreate]$ ps aux | grep ./hardTest
gongrui+  10153  0.0  0.0   4216   348 pts/0    T    13:40   0:00 ./hardTestExe
gongrui+  10157  0.0  0.0 112828   992 pts/0    R+   13:40   0:00 grep --color=auto ./hardTest
  • 在程式運行程序中我們按下 ctrl + z 就可以暫停行程運行,此時該行程的行程狀態是T,意為暫停狀態

  • 組合鍵 ctrl + z 本質上是SIGTSTP信號(20號信號),是一個暫停信號,讓正在運行的前臺程式暫停運行

2.3.3 產生核心轉儲檔案組合鍵 ctrl + |

[gongruiyang@localhost signalCreate]$ ./hardTestExe 
while回圈ing
while回圈ing
while回圈ing
^\Quit(core dumped)
[gongruiyang@localhost signalCreate]$ ls
core.10925  hardTest.c  hardTestExe
  • 在程式運行程序中我們按下 ctrl + | 就可以退出運行的行程,并產生一個core.XXX的核心轉儲檔案

  • 組合鍵 ctrl + | 本質上是SIGQUIT信號(3號信號),是一個結束行程并產生核心轉儲檔案 的信號

2.3.3.1 核心轉儲

  1. 核心轉儲檔案概念:核心轉儲檔案中存盤的是例外終止行程產生的一個檔案,行程終止瞬間將行程地址空間的內容以及有關行程狀態的其他資訊寫出的這個磁盤檔案,其中資訊常用于除錯尋找錯誤原因
  2. 核心轉儲概念:在UNIX系統中, 核心映像(core image) 就是行程(process)執行時的記憶體內容,當行程發生錯誤或收到“信號”(signal) 而終止執行時,系統會將核心映像寫入一個檔案,以作為除錯之用,這就是所謂的核心轉儲(core dump),

2.3.3.2 core file size設定

當行程例外退出或收到信號退出時,卻沒有產生核心轉儲檔案,此時可以通以下命令查看core file size設定情況,根據列印出來的內容可以看出core file size被設定為0,我們需要修改該設定值為unlimited后,行程例外退出后才能產生核心轉儲檔案

[gongruiyang@localhost signalCreate]$ 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) 14950
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
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) 4096
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

修改方式如下:

[gongruiyang@localhost signalCreate]$ ulimit -c unlimited
[gongruiyang@localhost signalCreate]$ ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 14950
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
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) 4096
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

2.3.3.3 使用gdb除錯核心轉儲檔案

#include <stdio.h>
void func()
{
  int* p = NULL;
  *p = 10;    //訪問空指標導致程式崩潰
}                              
int main()                     
{                              
  func();                      
                               
  return 0;                           
}                              
  • 上述程式,運行至第5行會訪問空指標,導致程式崩潰,行程例外退出,并產生一個核心轉儲檔案
[gongruiyang@localhost signalCreate]$ gcc corefiletest.c -g -o coretest
[gongruiyang@localhost signalCreate]$ ./coretest 
段錯誤(吐核)
[gongruiyang@localhost signalCreate]$ ls
core.58181  corefiletest.c  coretest  hardTest.c  hardTestExe

gdb除錯核心轉儲檔案尋找錯誤地方

[gongruiyang@localhost signalCreate]$ gdb [可執行檔案名] [核心轉儲檔案]
  • 使用gdb 可執行檔案 核心轉儲檔案 進入除錯界面

在這里插入圖片描述

  • 由除錯資訊可知:在func函式中由于11號信號導致程式終止,問題出現在func函式的第五行
(gdb) bt
#0  0x00000000004004fd in func () at corefiletest.c:5
#1  0x0000000000400513 in main () at corefiletest.c:9
(gdb) f 0
#0  0x00000000004004fd in func () at corefiletest.c:5
5	  *p = 10;    //訪問空指標導致程式崩潰
(gdb) p p
$1 = (int *) 0x0
  • 由列印的資訊可知 p變數中保存的地址為NULL,所以崩潰原因是對空指標進行了訪問

2.3.3.4 一些非法行為對應產生的信號量

非法行為信號量信號名
解參考空指標11號信號并產生核心轉儲檔案SIGSEGV
訪問越界11號信號并產生核心轉儲檔案SIGSEGV
動態分配空間free兩次6號信號并產生核心轉儲檔案SIGABRT

2.3 軟體產生的信號

2.3.1 kill

2.3.1.1 kill函式

int kill(pid_t pid, int sig);

功能:

頭檔案:

  • sys/types.h
  • signal.h

引數:

  • pid : 行程識別符號,給哪一個行程發送信號
  • sig : 信號值,具體發送哪一個信號

回傳值:

  • 成功:回傳信號值
  • 失敗:回傳 -1

測驗程式:測驗kill函式

#include <stdio.h>  
#include <sys/types.h>  
#include <signal.h>  
#include <unistd.h>  
int main()  
{  
  int ret_kill = kill(getpid(),2);  
  if(ret_kill == -1)  
    perror("kill");                   
  else  
    printf("信號量:%d\n",ret_kill);  
                         
  return 0;              
}                        
[gongruiyang@localhost signalinterface]$ ./killTest 

[gongruiyang@localhost signalinterface]$ 

2.3.1.2 kill命令

kill命令可以指定給具體行程發送具體信號量

kill -signal pid
  • signal:信號量,可以是具體數值,也可以是信號名字
  • pid : 行程識別符號

通過以下命令獲取行程pid

ps aux | grep 行程名
[gongruiyang@localhost TestSignal]$ ps aux |grep deadCircle
gongrui+  59789  0.0  0.0   4216   352 pts/0    S+   16:38   0:00 ./deadCircle
gongrui+  59797  0.0  0.0 112828   984 pts/1    R+   16:39   0:00 grep --color=auto deadC

通過kill -2干掉該行程,也可以使用9號信號量,該信號量是強殺信號,可以干掉大部分行程

[gongruiyang@localhost TestSignal]$ kill -2 59789

2.3.2 abort

2.3.2.1 abort函式

void abort(void);

功能:可以向行程發送SIGABRT信號(6號信號),使行程例外終止,并關閉重繪行程打開的流

頭檔案:

  • stdlib.h

哪一個行程呼叫該函式,便向該行程傳送SIGABRT信號(6號信號)

其實abort內部封裝了kill函式

3. 信號的注冊

3.1 行程中的未決信號集(位圖)

行程的task_struct中定義了位圖的初始定義

struct task_struct {
    ...
      struct sigpending pending;  
    ...
}

內核原始碼的include\linux\signal.h中sigpending

struct sigpending {
	struct list_head list;
	sigset_t signal;
};

內核原始碼的 include\asm-generic\signal.h中定義了sigset_t

typedef struct {
	unsigned long sig[_NSIG_WORDS];
} sigset_t;

內核原始碼的 include\asm-generic\signal.h中定義了**_NSIG_WORDS**

#define _NSIG		64
#define _NSIG_BPW	__BITS_PER_LONG
#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)

內核原始碼的 arch\alpha\include\asm\bitsperlong.h中定義了**__BITS_PER_LONG**

#define __BITS_PER_LONG 64
  • 一番檢查原始碼之后發現位圖就是一個unsigned long sig[1]

  • Linux作業系統中long占8個位元組,即64位

  • 每一個信號,在該位圖中存在一個與之對應的位元位

  • 當信號對應的位元位為1時,表示當前行程接收到該信號

3.1.1 圖解行程與未決信號集的關系

在這里插入圖片描述

3.2 非可靠信號注冊

前提:當前行程收到了一個非可靠信號

  1. 將當前行程的位圖中的對應非可靠信號位元位變成1
  2. 添加sigqueue節點到sigqueue佇列當中(如果該信號的sigqueue節點已經存在于sigqueue佇列中,則不添加

在這里插入圖片描述

3.3 可靠信號注冊

前提:當前行程收到一個可靠信號

  1. 將當前行程的位圖中的對應可靠信號的位元位變成1
  2. 添加sigqueue節點到sigqueue佇列當中(無論該信號的sigqueue節點是否存在于sigqueue佇列中,都要添加)

在這里插入圖片描述

3.4 sigqueue原始碼

struct sigqueue {
	struct list_head list;
	int flags;
	siginfo_t info;
	struct user_struct *user;
};

4. 信號的注銷

4.1 非可靠信號的注銷

前提:信號已經處理完

  1. 將處理完的信號對應位圖中的位元位從1變成0
  2. 將該信號的sigqueue節點從sigqueue佇列中出隊

4.2 可靠信號的注銷

前提:信號已經處理完了

  1. 將該信號的sigqueue節點從sigqueue佇列中出隊
  2. 需要判斷sigqueue佇列中是否還有與出隊的該信號相同的sigqueue節點
    • 還有相同的sigqueue節點:不修改位圖中的對應位元位
    • 沒有了:將該信號對應位圖中的位元位從1變成0

5. 信號的捕捉后的處理方式

#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */

5.1 默認處理方式SIG_DFL

#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
  • SIG_DFL就是 __sighandler_t結構體型別 的0

5.2 忽略處理方式SIG_IGN

典型的忽略處理方式:

僵尸行程的產生原因:子行程先于父行程退出,子行程向父行程發送了一個SIGCHLD信號,父行程接收到了該SIGCHLD信號,但是選擇了忽略處理的方式,導致了子行程的退出資源未被父行程進行回收,進而導致子行程變成了僵尸行程

#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
  • SIG_IGN就是 __sighandler_t結構體型別 的1

5.3 自定義信號處理方式

5.3.1 signal函式

自定義 信號處理方式 函式:程式員定義一個函式 去處理接收到的信號

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

功能:當行程接收到了signum信號時,呼叫handler函式,執行handler函式中的代碼,該信號以前需要執行的任務不再執行

頭檔案:

  • signal.h

引數:

  • signum : 信號量值,要處理的信號
  • handler : 信號處理句柄,就是一個函式指標,當行程接收到了signum這個信號時,行程需要呼叫handler函式去做一些事先規定好的事情

5.3.1.1 signal函式演示程式

#include <stdio.h>
#include <signal.h>
#include <unistd.h>          
void handler(int signum)     
{                            
  printf("接收到了2信號!\n");
}                            
int main()                   
{                            
  signal(2,handler);         
  sleep(10);      
    
  return 0;                  
}                            
[gongruiyang@localhost signalinterface]$ ./test 
^C接收到了2信號!

在Main行程在sleep時,按下ctrl + c組合鍵,向前臺行程main發送了一個2號信號,此時Main函式呼叫Handler函式,進行對信號的處理

5.3.2 sigaciotn函式

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

功能:自定義 信號處理方式 函式:程式員定義一個函式 去處理接收到的信號

頭檔案:

  • signal.h

引數:

  • signum : 信號量值
  • act : 輸入型引數,保存 對signum信號 所采取的措施資訊
  • oldact : 輸出型引數,保存 以前對signum信號 所采取的措施資訊

5.3.2.1 sigaction結構體詳解

struct sigaction {
    void     (*sa_handler)(int);	
    void     (*sa_sigaction)(int, siginfo_t *, void *); //自定義函式處理方式
    sigset_t   sa_mask;		//
    int        sa_flags;	//
    void     (*sa_restorer)(void);	//預留資訊
};
  • sa_handler:函式指標,保存了內核對信號的處理方式:默認處理方式忽略處理方式
  • sa_sigaction:函式指標,保存的時自定義處理函式
  • sa_mask:信號集位圖,保存收到的信號
  • sa_flags:填入宏
含義
SA_SIGINFO作業系統在處理信號的時候,呼叫的就是sa_sigaction函式指標當中保存的函式
0作業系統在處理信號的時候,呼叫的就是sa_handler函式指標當中保存的函式

5.3.2.2 sigaction函式程式演示

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

void handler(int signum)           
{
  printf("signum : %d\n",signum);
}

int main()
{
  struct sigaction act;
  sigemptyset(&(act.sa_mask));	//用于將位圖全部位 置為0
  act.sa_flags = 0;	//0表示 使用自定義函式
  act.sa_handler = handler;	//填寫 自定義函式

  sigaction(2,&act,NULL);

  while(1)
  {
    printf("Hello World!\n");
    sleep(1);
  }

  return 0;
}
[gongruiyang@localhost signalinterface]$ ./sigActionExe 
Hello World!
Hello World!
Hello World!
^Csignum : 2
Hello World!
Hello World!
Hello World!
^Csignum : 2
Hello World!
^Csignum : 2
Hello World!
Hello World!
Hello World!
  • 程式解釋:2號信號本來執行的是將中斷前臺行程,但是通過sigaction函式將2號信號的信號處理方式修改成了handler函式中的執行命令,所以在程式運行中,按下ctrl + c組合鍵不會將前臺程式進行中斷,只會執行handler函式

5.3.2.3 內核原始碼中的sigaction結構體原始碼

struct sigaction {
	union {
	  __sighandler_t	_sa_handler;
	  void (*_sa_sigaction)(int, struct siginfo *, void *);
	} _u;
	sigset_t	sa_mask;
	int		sa_flags;
};
#define sa_handler	_u._sa_handler
#define sa_sigaction	_u._sa_sigaction

typedef char* __user __sighandler_t;
typedef struct {
	unsigned long sig[_NSIG_WORDS];
} sigset_t;

5.3.3 signal函式與sigaction函式的關系

  • signal函式只是修改了sigaction結構體中的_sa_sigaction
  • sigaction函式修改了整個sigaction結構體
  • signal函式內部呼叫了sigaction函式

6. 探究回呼函式機制的原始碼定義

6.1 從task_struct到回呼函式handler的結構體嵌套原始碼

  • 在task_struct中找到sighand_struct結構體指標
task_struct{
	...
	struct sighand_struct *sighand;
	...
}
  • sighand_struct結構體定義
struct sighand_struct {
	...
	struct k_sigaction	action[_NSIG];
	...
};
  • k_sigaction結構體定義
struct k_sigaction {
	struct sigaction sa;
    ...
};
  • sigaction結構體定義
struct sigaction {
	union {
	  __sighandler_t	_sa_handler;
	  void (*_sa_sigaction)(int, struct siginfo *, void *);
	} _u;
	sigset_t	sa_mask;
	int		sa_flags;
};
#define sa_handler	_u._sa_handler
#define sa_sigaction	_u._sa_sigaction

#ifdef CONFIG_64BIT
/* function pointers on 64-bit parisc are pointers to little structs and the
 * compiler doesn't support code which changes or tests the address of
 * the function in the little struct.  This is really ugly -PB
 */
typedef char __user *__sighandler_t; 
#else
typedef void __signalfn_t(int);
typedef __signalfn_t __user *__sighandler_t;
#endif	

6.1 圖解結構體嵌套關系

在這里插入圖片描述

6.2 原始碼中__sighandler_t的決議

#ifdef CONFIG_64BIT
/* function pointers on 64-bit parisc are pointers to little structs and the
 * compiler doesn't support code which changes or tests the address of
 * the function in the little struct.  This is really ugly -PB
 */
typedef char __user *__sighandler_t; 
#else
typedef void __signalfn_t(int);
typedef __signalfn_t __user *__sighandler_t;
#endif	
  • 由注釋可以看出:__sighandler_t是一個函式指標(function pointer),并且很難看出來,十分的ugly

剛開始沒有注意看這個注釋,博主就想char*咋能是函式指標呢?原始碼翻來覆去苦苦尋找__sighandler_t是否還有其它的宏定義,后來仔細讀了一下原始碼注釋,才豁然開朗,TMD,絕了,十分ugly

7. 信號的捕捉流程

在這里插入圖片描述

  • main函式呼叫了一個系統呼叫函式或者呼叫**庫函式(庫函式底層也是封裝的系統呼叫函式)**后,cpu從用戶態切換到內核態
  • 內核態呼叫系統呼叫后想回到用戶態需要呼叫do_signal函式
  • do_signal函式的功能是檢查行程是否接受到信號:
    • 如果接受到信號,呼叫sigcb函式去處理信號(1**.默認處理方式則不需要切換到用戶態,直接在內核態進行信號處理;2.自定義處理方式需要切換到用戶態**進行信號處理),信號處理完畢后呼叫sig_return函式表明信號處理完,再呼叫do_signal函式檢查是否接受到新的信號
    • 如果未接收到信號,直接呼叫sys_return函式,讓cpu從內核態切換到用戶態

8. 信號阻塞

8.1 信號阻塞概念及內核原始碼定義

task_struct原始碼中定義了信號阻塞位圖和信號注冊位圖

struct task_struct{
	...
	sigset_t blocked, real_blocked;	// 信號阻塞位圖
	struct sigpending pending;	// 信號注冊位圖 位于這個結構體內部
	...
}
  • 當信號阻塞位圖block中對應信號的位為1,表示當前行程阻塞該信號
  • 當行程進入內核狀態,準備回傳到用戶態時,呼叫do_signal函式時,接收到了一個信號,如果該信號的阻塞位圖中的對應位置為1,則不會立即去處理該信號
  • 等到該信號的阻塞位圖上的該信號對應位變成1之后才會去處理該信號,可靠信號發送了幾次處理幾次,非可靠信號發送大于等于1次都是處理1次

8.2 設定阻塞位圖函式

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

功能:設定阻塞位圖

頭檔案:

  • signal.h

引數:

  • how : 告訴函式應該做什么,填入宏
含義
SIG_BLOCK設定某個信號為阻塞
SIG_UNBLOCK解除對某個信號的阻塞
SIG_SETMASK替換阻塞位圖
  • set : 新替換入的阻塞位圖,可以為NULL
  • alodset : 原阻塞位圖,可以為NULL

SIG_BLOCK設定阻塞原理:按位或,便將新的要阻塞的信號加入了阻塞位圖中 (原阻塞位圖 | 新阻塞位圖)

SIG_UNBLOCK解除阻塞原理:按位與,便將要解除阻塞的信號的位元位變成0(原阻塞位圖 & 新阻塞位圖)

8.2.1 程式演示

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void handler(int signum)
{
  printf("signum : %d\n",signum);    
}
int main()
{
  signal(2,handler);
  signal(40,handler);

  sigset_t set;
  sigfillset(&set);	// 位圖全部置為1

  sigprocmask(SIG_SETMASK,&set,NULL);
  while(1)
  {
    printf("Hello!\n");
    sleep(1);
  }

  return 0;
}

該程式運行起來后,該行程阻塞了所有信號除了 kill -9 其他信號都沒用

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/245304.html

標籤:其他

上一篇:shell腳本快速創建格式化磁盤與詳細操作程序

下一篇:預防“吃人”事件,NB-IoT智能井蓋“上崗上線”

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more