信号使用方法
2015-06-30 12:27
183 查看
信号基本使用方法
信号:
首先计算机是一个很会营造假象的机器,它欺骗每一个进程,线程。使他们误以为自己就是唯一使用资源的进线程,但是者也造成了一个问题,进线程们都变得比较自我,想让他们互相之间通信,或者我们和他们通信就必须使用一些 “手段“ 。向他们发送信号就是一种很好的方法。
首先在LINUX下就有很多信号,当前共有64个其中32,33号信号暂时没有设定。
$ 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的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为34 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。
一般使用kill -signum PID 来发送信号。
信号虽然多但是很大一部分可以根据他们的名字来分辨他们功能。
kill( )信号发送函数:
int sig_send(pid_t id,int sig) { if(kill(id,sig)){ printf("mission failed [%d]\n",errno); } return 0; }
这个函数接受俩个参数,一个是进程的id,另一个是信号名称。使用Kill 函数将信号发送给id进程。
sigalarm & pause
#include
#include <apue.h> int main() { if(!alarm(5)){ } pause(); }
这个程序简单的展现了这两个函数配合使用的效果。
signal( )函数:
#include
void int_hander(int sig) { printf("got signal : %d\n",sig); exit(0); } int main() { int sig = 1; while(1){ if(SIG_ERR == signal(sig,int_hander)){ printf("signale error %d\n",sig); } sleep(1); }
#include <signal.h> int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set, int signum); int sigdelset(sigset_t *set, int signum); int sigismember(const sigset_t *set, int signum); 这是信号修改一族的函数,分别的作用为: 这里的信号集都是要屏蔽的信号 int sigemptyset(sigset_t *set);清空整个信号集 int sigfillset(sigset_t *set);添加所有信号进信号集 int sigaddset(sigset_t *set, int signum);追加signum信号进信号集 int sigdelset(sigset_t *set, int signum);从信号集中删除信号signum int sigismember(const sigset_t *set, int signum);用来测试参数signum是否已经添加到信号集 #include <signal.h> int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); 这个函数主要是用来设置信号集的,其中how 有三个参数 SIG_BLOCK 追加屏蔽信号到信号屏蔽关键字里去 SIG—UNBLOCK 解放传进来的信号 SIG_SETMASK 接受传参的信号位屏蔽信号
#include <apue.h> void sigmask_blockall() { sigset_t sigset,oldset; sigemptyset(&sigset); sigemptyset(&oldset); sigfillset(&sigset); sigdelset(&sigset,SIGKILL); sigdelset(&sigset,SIGSTOP); if(sigprocmask(SIG_SETMASK,&sigset,&oldset)){ printf("sigprocmask error : %d\n",errno); } } void sigmask_blocksig(int sig) { sigset_t sigset,oldset; sigemptyset(&sigset); sigemptyset(&oldset); sigaddset(&sigset,sig); if(sigprocmask(SIG_BLOCK,&sigset,&oldset)){ printf("sigprocmask error : %d\n",errno); } } void sigmask_freeall() { sigset_t sigset,oldset; sigemptyset(&sigset); sigemptyset(&oldset); if(sigprocmask(SIG_SETMASK,&sigset,&oldset)){ printf("sigprocmask error : %d\n",errno); } } void usage(char *cmd) { printf("Usage : %s <1|2|3>\n",cmd); } int main(int ac,char **av) { int route = 0; if(1 >= ac){ usage(av[0]); return 1; } route = atoi(av[1]); switch(route){ case 1: sigmask_blockall(); break; case 2: sigmask_blocksig(SIGINT); break; case 3: sigmask_freeall(); break; default: usage(av[0]); //printf("Only 1,2,3 is OK\n"); break; }//end switch while(1){ sleep(1); } }
这个函数展示了设置信号屏蔽字的三种方式。
sigpending()
#include
#include <apue.h> void sig_hander(int sig) { printf("got sig : %d\n",sig); } void sig_set(sigset_t *set,int sig) { if(NULL == set){ return; } sigemptyset(set); if(SIGRTMAX < sig){ sigfillset(set); }else{ sigaddset(set,sig); } } int main() { sigset_t set,old,pend; int sig = 1; while(sig < 65){ if(SIG_ERR == signal(sig,sig_hander)){ //error } ++sig; } sig_set(&set,65); if(sigprocmask(SIG_BLOCK,&set,NULL)){ //error } sigemptyset(&pend); /* 本函数将挂起,直到某个信号出现打断。 * 函数返回后,屏蔽字将还原。 * 函数返回前,进程的屏蔽字,将被临时替换。 */ sigsuspend(&pend); printf("suspend end\n"); while(1){ sleep(1); } return 0; }
相关文章推荐
- Java的StringTokenizer类
- 张国祥老师应邀参加联创世纪五周年庆压轴大戏暨公司化运作高峰论坛活动
- How to use JUnit in Eclipse?
- Asp.net 按钮防止点击多次数据提交
- H264基本概念之 宏块、片和片组
- 程序员为了期权加入创业公司,值得吗?
- 三种方法解决 Failed to start LSB: Bring up/down networking 问题
- SQL语句的执行原理分析
- Python Mixin
- 112.按规定删除字符串中的字符
- org.hibernate.hql.ast.QuerySyntaxException: User is not mapped [from User]
- RC4文件加密的python实现方法
- Hadoop第七讲(2)
- .net使用Newtonsoft.Json.dll解析json过程的几种特殊情况处理
- fancybox 最基本的使用步骤
- MySQL日期数据类型、时间类型使用总结
- 《Programming In Lua》书上一个有问题的代码
- SQL Server 数据库备份和还原认识和总结(二)
- Linux服务器管理: 系统的进程管理ps命令
- swift循环