Linux系統編程——進程間通信:int kill()信號中斷

複習參考:https://blog.csdn.net/weibo1230123/article/details/81411827
複習:https://blog.csdn.net/tennysonsky/article/details/46010303

查看信號 kill -l
*同步是指:發送方發出數據後,等接收方發回響應以後才發下一個數據包的通訊方式。
*異步是指:發送方發出數據後,不等接收方發回響應,接着發送下個數據包的通訊方式。

在這裏插入圖片描述

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>

void print_signal(sigset_t sset){

	for (int i = 1; i < 32; ++i)
	{
		//判斷信號是否存在信號集裏面是則返回 1
		if(sigismember(&sset,i)){
			putchar('1');
		}else{
			putchar('0');
		}
	}
	putchar('\n');
}
int main(){

	/*
	*屏蔽信號描述:先創造信號集合,清空集合裏面的數,在添加堵塞進程
	*注意:SIGKILL 和 SIGSTOP 不能更改信號的處理方式,因爲它們向用戶提供了一種使進程終止的可靠方法
	*/
	//信號集合
	sigset_t siggrop,pendgrop;
	//信號初始化
	sigemptyset(&siggrop);
	//可以設置block
	sigaddset(&siggrop,SIGINT);
	
	//設置信號屏蔽信號集合
	sigprocmask(SIG_SETMASK,&siggrop,NULL);//最後參數保存前面block 的狀態,恢復現場
	


	while(1){
				//打印pengding信號
				sigpending(&pendgrop);
				print_signal(pendgrop);
				sleep(1);
				//printf("iam \n");
			}
}

圖中的2號信號(SIGINT--Ctrl+c)當輸入時打印出1sigaction函數的使用

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

/*
一、函數原型: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此參數和signal()的參數handler相同,代表新的信號處理函數
sa_mask 用來設置在處理該信號時暫時將sa_mask 指定的信號集擱置
sa_flags 用來設置信號處理的其他相關操作,下列的數值可用。 
SA_RESETHAND:當調用信號處理函數時,將信號的處理函數重置爲缺省值SIG_DFL
SA_RESTART:如果信號中斷了進程的某個系統調用,則系統自動啓動該系統調用
SA_NODEFER :一般情況下, 當信號處理函數運行時,內核將阻塞該給定信號。但是如果設置了 SA_NODEFER標記, 那麼在該信號處理函數運行時,內核將不會阻塞該信號

*
*/

void myhandler(int a){

	printf("a=%d\n",a);//a是信號處理函數傳遞信號
	sleep(6);
	printf("over\n");

}
int main(int argc, char const *argv[])
{
	sigset_t block_grp;
	sigemptyset(&block_grp);
	sigaddset(&block_grp,0);


	struct sigaction  myact;

	myact.sa_handler = myhandler;

	//爲空則只執行這個信號的函數,若有兩個信號
	//則要在處理這個信號函數的時候要屏蔽別的信號然後處理完以後在執行另外一個信號
	myact.sa_mask = block_grp;

	sigaction(SIGINT,&myact,NULL);
	alarm(3);

	while(1){
				//該函數的作用是將被阻塞的信號中停
				//留在待處理狀態的一組信號寫到參數set指向的信號集中,
				//成功調用返回0,否則返回-1,並設置errno表明錯誤原因
				/*sigpending(&pendgrop);

				print_signal(pendgrop);*/
				sleep(1);
				//printf("iam \n");
			}

	return 0;
}

在這裏插入圖片描述
利用sa_mask設置屏蔽其他信號

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

void myhandler(int a){

	printf("a=%d\n",a);//a是信號處理函數傳遞信號
	sleep(6);
	printf("over\n");

}
int main(int argc, char const *argv[])
{
	sigset_t block_grp;
	sigemptyset(&block_grp);
	sigaddset(&block_grp,14);


	struct sigaction  myact;

	myact.sa_handler = myhandler;

	//爲空則只執行這個信號的函數,若有兩個信號
	//則要在處理這個信號函數的時候要屏蔽別的信號然後處理完以後在執行另外一個信號
	myact.sa_mask = block_grp;

	sigaction(SIGINT,&myact,NULL);
	alarm(3);

	while(1){
				//該函數的作用是將被阻塞的信號中停
				//留在待處理狀態的一組信號寫到參數set指向的信號集中,
				//成功調用返回0,否則返回-1,並設置errno表明錯誤原因
				/*sigpending(&pendgrop);

				print_signal(pendgrop);*/
				sleep(1);
				//printf("iam \n");
			}

	return 0;
}

在這裏插入圖片描述

對比兩個代碼不同之處在於	sigaddset(&block_grp,14);是否設置在處理一個信號函數的時候讓另外一個信號阻塞
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章