UC编程8-信号发送函数kill/raise/setitimer/alarm和信号集函数segprocmask

//myuc.h

#include<stdio.h>//io流
#include<stdlib.h>//标准库
#include<unistd.h>//uc标准头文件
#include<fcntl.h>//文件控制
#include<string.h>//c字符串
#include<sys/types.h>
#include<sys/mman.h>//内存映射
#include<sys/stat.h>//文件状态信息
#include<sys/wait.h>//进程等等
#include<dirent.h>//目录操作
#include<signal.h>//信号
#include<sys/time.h>//时间,计时器
#include<sys/ipc.h>//ipc进程间通信
#include<sys/shm.h>//共享内存段
#include<sys/msg.h>//消息队列


//8itimer.c

#include "myuc.h"
void fa(int signo){
printf("get signo %d\n",signo);
}
void test1(){
	signal(SIGALRM,fa);
	struct itimerval timer;
	timer.it_interval.tv_sec=3;//循环时间
	timer.it_interval.tv_usec=100000;//0.1秒
	timer.it_value.tv_sec=2;//开始时间
	timer.it_value.tv_usec=100000;
	setitimer(ITIMER_REAL,&timer,NULL);
	//设定循环向本进程发送SIGALRM信号。
	while(1);
}
void test2(){

}
int main()
{
	test1();
	test2();
	return 0;
}

//8killalarm.c

#include "myuc.h"
void fa(int signal){
	printf("pid:%d catched signal %d\n",getpid(),signal);
	if(signal==SIGALRM){
	printf("闹钟信号\n");
	alarm(2);
	}
}
//raise发信号
void test1(){
	signal(SIGINT,fa);
	raise(SIGINT);//给自己发信号
	int lefts=sleep(3);//时间到或者非忽略信号到来时,就执行后面的代码
	usleep(3000000);// 微妙,10(-6次方),不会被信号打断
	if(lefts!=0) printf("lefts=%d\n",lefts);//lefts为sleep的剩余秒数
	raise(SIGQUIT);
	while(1);
}
//kill发信号
void test2(){
pid_t pid=fork();
if(pid==0){
	signal(SIGINT,fa);
	printf("child:pid=%d\n",getpid());
	//while(1);
	sleep(10);
	printf("child end\n");
	exit(1);
}
sleep(1);
printf("send signal\n");
kill(pid,SIGINT);
sleep(2);
printf("father end\n");
}
//闹钟信号
void test3(){
	
	signal(SIGALRM,fa);
	alarm(10);
	sleep(1);
	int res=alarm(5);//返回上一个闹钟剩余秒数
	printf("res=%d\n",res);
	sleep(1);
	res=alarm(2);//alarm秒数到了,才发出信号
	printf("res=%d\n",res);
	while(1);
}
int main()
{
	//test1();
	//test2();
	test3();
	return 0;
}

//8sigaction.c

#include "myuc.h"
void fa(int signo){
	printf("catched signal %d\n",signo);
	sleep(2);
	printf("sleep end\n");
}
void fa2(int signo,siginfo_t * info,void * p){
printf("catched signal %d from %d\n",signo,info->si_pid);
}
void fa3(int signo,siginfo_t * info,void * p){
printf("catched signal %d from %d,data:%d\n",
		signo,info->si_pid,info->si_value);
}
void test1(){
	struct sigaction act={};
	act.sa_handler=fa;//函数指针
	sigemptyset(&act.sa_mask);
	sigaddset(&act.sa_mask,3);
	act.sa_flags=SA_NOMASK|SA_RESETHAND;
	//不屏蔽自身|执行一次恢复默认
	sigaction(SIGINT,&act,NULL);
	while(1);
}
void test2(){
	printf("mypid=%d\n",getpid());
	struct sigaction act={};
	act.sa_sigaction=fa2;//函数指针
	sigemptyset(&act.sa_mask);
	
	act.sa_flags=SA_NOMASK|SA_SIGINFO;
	//不屏蔽自身|执行一次恢复默认
	sigaction(SIGINT,&act,NULL);
	while(1);
}
void test3(){
	printf("mypid=%d\n",getpid());
	struct sigaction act={};
	act.sa_sigaction=fa3;//函数指针
	sigemptyset(&act.sa_mask);
	
	act.sa_flags=SA_NOMASK|SA_SIGINFO;
	//不屏蔽自身|使用sa_sigaction函数处理
	sigaction(/*SIGINT*/40,&act,NULL);
	pid_t pid=fork();
	if(pid==0){
		int i;
		for(i=0;i<20;i++)
		{
			union sigval v;
			v.sival_int=i;
			sigqueue(getppid(),/*2*/40,v);//给父进程发信号,带数据
		}
		exit(1);
	}
	while(1);
}
int main()
{
	//test1();
	//test2();
	test3();
	return 0;
}

//8sigset.c

#include "myuc.h"
void fa(int signo){
printf("catched signal %d\n",signo);
}
//信号集合操作
void test1(){
printf("size=%d\n",sizeof(sigset_t));
sigset_t set;
printf("set=%g\n",set);
sigemptyset(&set);
printf("set=%d\n",set);
sigaddset(&set,2);//倒数第2位置1
printf("set=%d\n",set);
sigaddset(&set,3);//倒数第3位置1
printf("set=%d\n",set);
if(sigismember(&set,2)){
	printf("signal 2 exist\n");
}
}
//信号屏蔽和解除
void test2(){
signal(SIGINT,fa);
signal(SIGQUIT,fa);
signal(40,fa);//自定义处理40的信号
printf("pid=%d\n",getpid());
printf("信号没屏蔽\n");
sleep(10);
printf("信号屏蔽\n");
sigset_t set,oldset;
sigemptyset(&set);
sigaddset(&set,2);sigaddset(&set,3);//不可靠信号,多种相同信号只保留一个
sigaddset(&set,40);//可靠信号
sigprocmask(SIG_SETMASK,&set,&oldset);
sleep(5);
printf("获取屏蔽期收到的信号\n");
sigset_t recset;
sigpending(&recset);//接收屏蔽期间收到过的信号集合,不能获取次数
if(sigismember(&recset,2)){
	printf("接收到信号2\n");
}
else{
	printf("没收到信号2\n");
}
printf("屏蔽解除\n");
sigprocmask(SIG_SETMASK,&oldset,NULL);//解除屏蔽之后,会处理之前接收到的信号

}
int main()
{
 	//test1();
	test2();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值