0
点赞
收藏
分享

微信扫一扫

进程通信——信号

西街小学的王 2022-01-04 阅读 63
c语言

一、信号

信号是在软件层次上对中断机制的一种模拟。在原来上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的:一个进程不必通过任何操作来等待信号的到达。信号可以之间进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间发生了哪些系统事件。它可以在任何时候发给某一进程,而无需知道该进程的状态。如果该进程当前并未处于执行态,则该信号由内核保存起来,直到该进程恢复执行再传递给它为止;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。

如下命令查看信号及其编号:

 

进程可以通过三种方式来响应一个信号:

1.忽略信号:即对信号不做任何处理,其中,有两个信号不能被忽略:SIGKILL及SIGSTOP

2.捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数

3.执行默认操作:Linux对每种命令都规定了默认操作

二、主要函数

       #include <sys/types.h>
       #include <signal.h>

       int kill(pid_t pid, int sig);
——————————————————————————————————————————————————————
       #include <signal.h>

       int raise(int sig);
——————————————————————————————————————————————————————
       #include <unistd.h>

       unsigned int alarm(unsigned int seconds);
——————————————————————————————————————————————————————
       #include <unistd.h>

       int pause(void);
——————————————————————————————————————————————————————
       #include <signal.h>

       typedef void (*sighandler_t)(int);

       sighandler_t signal(int signum, sighandler_t handler);
______________________________________________________
       #include <signal.h>

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

三、实例

1.信号发送:kill()和raise()

/*########################################################################
# File Name: kill.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 22时34分32秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)
#define qDbug() do { puts(_STR(__LINE__)); } while(0)

#include<sys/types.h>
#include<signal.h>
#include<unistd.h>

int main(int argc,char **argv){
	if(ERRVAL == kill(getpid(), SIGKILL)) handle_error("kill");
	return 0;
}
/*########################################################################
# File Name: raise.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 22时40分49秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)
#define qDbug() do { puts(_STR(__LINE__)); } while(0)

#include<signal.h>

int main(int argc,char **argv){
	if(0 != raise(3)) handle_error("raise");
	return 0;
}

2.定时器信号:alarm()和pause()

/*########################################################################
# File Name: alarm_pause.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 22时42分54秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)
#define qDbug() do { puts(_STR(__LINE__)); } while(0)

#include<unistd.h>
#include<signal.h>
#include<sys/time.h>
#define DELAY_TIME 5
int count = 0;
/*
void setitimer_out(){
	printf("%d\n", count++);
}
*/
int main(int argc,char **argv){
#if 0
	struct sigaction act;
	act.sa_handler = setitimer_out;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);
	sigaction(SIGPROF, &act, NULL);

	struct itimerval val;
	val.it_value.tv_sec = 1;
	val.it_value.tv_usec = 0;
	val.it_interval = val.it_value;
	setitimer(ITIMER_PROF, &val, NULL);

	while(1);
#endif
	printf("alarm_retval = %d\n", alarm(DELAY_TIME));
	printf("alarm_retval = %d\n", 2*alarm(DELAY_TIME));
	printf("alarm_retval = %d\n", 3*alarm(DELAY_TIME));
	if(ERRVAL == pause()) handle_error("pause");
	return 0;
}

 定时器alarm只能设定一个,后面设定的alarm返回值为该函数的剩余时间

3.信号的设置:signal()和sigaction()

/*########################################################################
# File Name: sig_parent.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 16时57分37秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)

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

void sighandler_t(int signum);

int main(int argc,char **argv){
	pid_t pid;
	if(ERRVAL == (pid = fork()))handle_error("fork");
	if(0 == pid){
		sleep(2);
		exit(EXIT_SUCCESS);
	}
	else{
		int *status;
		signal(SIGCHLD, sighandler_t);
		wait(status);
	}
	return 0;
}

void sighandler_t(int signum){
	while(1){
		printf("child exit-----\n");
		sleep(1);
	}
}
/*########################################################################
# File Name: alarm_pause.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 22时42分54秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)
#define qDbug() do { puts(_STR(__LINE__)); } while(0)

#include<unistd.h>
#include<signal.h>
#include<sys/time.h>
#define DELAY_TIME 5
int count = 0;

void setitimer_out(){
	printf("%d\n", count++);
}

int main(int argc,char **argv){
	struct sigaction act;
	act.sa_handler = setitimer_out;
	act.sa_flags = 0;
	sigemptyset(&act.sa_mask);
	sigaction(SIGPROF, &act, NULL);

	struct itimerval val;
	val.it_value.tv_sec = 1;
	val.it_value.tv_usec = 0;
	val.it_interval = val.it_value;
	setitimer(ITIMER_PROF, &val, NULL);

	while(1);
//	printf("alarm_retval = %d\n", alarm(DELAY_TIME));
//	printf("alarm_retval = %d\n", 2*alarm(DELAY_TIME));
//	printf("alarm_retval = %d\n", 3*alarm(DELAY_TIME));
//	if(ERRVAL == pause()) handle_error("pause");
	return 0;
}

sigaction可以为特定的信号设置处理函数,并且可以保存上一次的处理方式

举报

相关推荐

0 条评论