信号与信号集
# core文件使用
如果要使用core文件,首先将core设置文件大小
ulimit -a //查看各种文件大小限制 ulimit -c 1024 //将core文件大小设置为1024,c表示core文件,从-a的列表中可以看到
设置大小之后,再进行编译,如果不成功则会生成core文件
使用gdb调试
core-file core文件名
# kill raise abort alarm
/* #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig); 功能:给任何进程或进程组发送任何信号 参数: pid: > 0:将信号发送给指定进程 = 0:将信号发送给当前的进程组 = -1:将信号发送给每一个有权限接收这个信号的进程 < -1:将信号发送给gid = |pid|的进程组 sig:需要发送的信号编号或宏值,0表示不发送任何信号 #include <signal.h> int raise(int sig); 功能:给当前进程发送信号 参数: sig:要发送的信号 返回值: 成功:0 失败:非0 == kill(getpid(), sig) #include <stdlib.h> void abort(void); 功能:发送SIGABRT给当前进程,杀死当前进程 == kill(getpid(), SIGABRT); #include <unistd.h> unsigned int alarm(unsigned int seconds); 功能:设置定时器,当倒计时为0时,给当前进程发送SIGALARM信号 如果之前有定时器,则会覆盖之前的定时器,即只有一个有效的定时器 参数: seconds:倒计时的时长,如果参数为0,则定时器无效;取消一个定时器,通过alarm(0) SIGALARM:默认终止当前进程 返回值: -之前没有定时器:返回0 -之前有定时器:返回之前定时器剩余的时间 */ // 计算机一秒能数多少个数 #include <unistd.h> #include <stdio.h> int main() { alarm(1); int i = 0; while(1) { printf("%d\n", ++i); } return 0; }
# setitimer 周期时钟
/* 周期时钟 #include <sys/time.h> int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value); 功能:周期时钟 参数: which:时钟时间类型 - ITIMER_REAL:cpu时间,时间到发送SIGALRM - ITIMER_VIRTUAL:用户时间,SIGVTALRM - ITIMER_PROF:cpu + 用户,SIGPROF new_value:时钟属性 struct itimerval { //时钟结构体 struct timeval it_interval; // 周期时间 struct timeval it_value; // 执行延迟时间 }; struct timeval { // 时间结构体 time_t tv_sec; // 秒数 suseconds_t tv_usec; // 微秒 }; old_value:记录上次的new_value,一般可以以NULL代替 返回值: 成功:0 失败:-1 */ // 过3秒后,每隔2秒定时一次 #include <sys/time.h> #include <stdio.h> #include <stdlib.h> int main() { struct itimerval new_value; new_value.it_interval.tv_sec = 2; new_value.it_interval.tv_usec = 0; new_value.it_value.tv_sec = 3; new_value.it_value.tv_usec = 0; int ret = setitimer(ITIMER_REAL, &new_value, NULL); if(ret == -1) { perror("setitimer"); exit(-1); } getchar(); return 0; }
# 信号捕捉
/* 信号捕捉 #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); // 写到最前面 功能:捕捉某个信号 参数: signum:要捕捉的信号 handler:处理方式 - SIG_IGN:忽略信号 - SIG_DFL:使用信号默认处理方式 - 回调函数:自定义的信号处理函数 返回值: 成功:返回上一次注册的信号处理函数的地址,第一次调用返回NULL 失败:返回SIG_ERR,并设置错误号 - SIGKILL 和 SIGSTOP不能被捕捉,也不能被忽略 */ #include <sys/time.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> void print(int num) { printf("到时间啦!\n"); } int main() { // void (*handle) (int) = &print; // signal(SIGALRM, SIG_DFL); // signal(SIGALRM, SIG_IGN); signal(SIGALRM, &print); struct itimerval new_value; new_value.it_interval.tv_sec = 2; new_value.it_interval.tv_usec = 0; new_value.it_value.tv_sec = 3; new_value.it_value.tv_usec = 0; int ret = setitimer(ITIMER_REAL, &new_value, NULL); if(ret == -1) { perror("setitimer"); exit(-1); } getchar(); return 0; }
# 信号集
/* 以下函数都是对自定义的信号集有效 信号集是一个位图,用整数表示即可,二进制相应的位为1表示被阻塞 #include <signal.h> int sigemptyset(sigset_t *set); 功能:清空信号集中的数据,将信号集中的所有标志位置为0 参数:set:传出参数,需要操作的信号集 返回值:成功0,失败-1 int sigfillset(sigset_t *set); 功能:将信号集中的所有标志位置为1 参数:set:传出参数,需要操作的信号集 返回值:成功0,失败-1 int sigaddset(sigset_t *set, int signum); 功能:设置信号集中的某一个信号对应的标志位为1,表示阻塞这个信号 参数: - set:传出参数,需要操作的信号集 - signum:需要阻塞的信号 返回值:成功0,失败-1 int sigdelset(sigset_t *set, int signum); 功能:设置信号集中的某一个信号对应的标志位为0,表示不阻塞这个信号 参数: - set:传出参数,需要操作的信号集 - signum:需要不阻塞的信号 返回值:成功0,失败-1 int sigismember(const sigset_t *set, int signum); 功能:判断signum是否堵塞 参数: - set:需要操作的信号集 - signum:需要判断的信号 返回值: 1: 被阻塞 0:不被阻塞 -1:失败 */ #include <signal.h> #include <stdio.h> int main() { sigset_t sigset; sigemptyset(&sigset); printf("flag is : %d\n", sigismember(&sigset, SIGABRT)); sigaddset(&sigset, SIGABRT); printf("flag is : %d\n", sigismember(&sigset, SIGABRT)); sigdelset(&sigset, SIGABRT); printf("flag is : %d\n", sigismember(&sigset, SIGABRT)); return 0; }
# 阻塞信号集和未决信号集
/* #include <signal.h> int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); 功能:将自定义的信号集中的数据设置到内核中 参数: how:如何对内核阻塞信号集进行处理 SIG_BLOCK:将用户设置的阻塞信号添加到内核中, == mask | set SIG_UNBLOCK:根据用户设置的数据,解除相应信号的阻塞, == mask & ~set SIG_SETMASK:覆盖内核中原来的set set:用户自定义的信号集 oldset:保存之前内核中阻塞信号集,一般为NULL 返回值: 成功:0 失败:-1 #include <signal.h> int sigpending(sigset_t *set); 功能:获取内核中的未决信号集 参数: set:传出参数 */ // 获取包含1-31号的未决信号集 #include <stdio.h> #include <signal.h> int main() { sigset_t signalset; sigpending(&signalset); sigaddset(&signalset, 2); sigaddset(&signalset, 3); sigprocmask(SIG_SETMASK, &signalset, NULL); while(1) { sigset_t pendingset; sigemptyset(&pendingset); sigpending(&pendingset); for(int i = 1; i < 32; i++) { if(sigismember(&pendingset, i)) printf("0"); else printf("1"); } printf("\n"); sleep(1); } return 0; }
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。