i.MX6ULL终结者进程间通信信号

信号是非常重要的一种进程通信机制,模拟硬件中断,当某个事件发生后,Linux内核通过发信号通知进程去处理,打断进程的执行,比如在i.mx6ull终结者使用文档/ Linux异步通知实验中就使用了信号机制。
信号机制使用一些系统调用在内核注册信号,事件发送后发送信号,进程收到信号后会进行处理,处理方式有以下三种:
1.默认方式(通常是终止进程),
2.忽略,不进行任何操作。
3.捕捉并处理调用信号处理器(回调函数形式)。
本章只关注在应用层对信号的处理,如果想进一步体验信号可以在驱动章节体验异步通知。在Ubuntu终端输入kill -l,查看所有的信号,具体可查看Linux异步通知实验章节:

  1. SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
  2. SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
  3. SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
  4. SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
  5. SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
  6. SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
  7. SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3

下面是几个常用的函数:
信号处理函数:
signal():改变收到信号后的动作。
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
函数功能:信号signum发送后执行 handler。
参数含义:
signum:要捕获的信号类型。
handler:对信号的处理操作,三种处理方式如下:
忽略该信号,填写“SIG_IGN”;
采用系统默认方式处理该信号,填写“SIG_DFL”;
捕获到信号后执行此函数内容,定义格式为“typedef void (*sighandler_t)(int)”,sighandler_t代表一个函数指针。
返回值:调用成功返回最后一次注册信号调用signal()时的handler值;失败返回SIG_ERR。

kill():发送信号
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
参数含义:
pid:大于0,时为向PID为pid的进程发送信号;
等于0,向同一个进程组的进程发送信号;
等于-1,除发送进程自身外,向所有进程ID大于1的进程发送信号。
小于-1,向组ID等于该pid绝对值的进程组内所有进程发送信号。
sig:设置发送的信号;等于0时为空信号,无信号发送。常用来进行错误检查。
返回值:执行成功时,返回值为0;错误时,返回-1,并设置相应的错误代码errno。

raise():向进程自身发送信号:
#include <signal.h>
int raise(int sig);
sig:信号。
函数功能:相当于kill(getpid(),sig)。

pause():暂停进程,等待信号中断。
#include <unistd.h>
int pause(void);
返回值:进程被信号中断后一直返回-1,
函数功能:将进程挂起,等待信号。

alarm():定时
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
参数含义:设定的时间
函数功能:设定的时间超过后产生SIGALARM信号,默认动作是终止进程。
使用规则:每个进程只能有一个alarm()函数,时间到后要想再次使用要重新注册。

实验1代码:路径为:11_Linux系统开发进阶\Linux系统编程_章节使用资料。
在程序中实现:改变终端窗口大小三次终止进程。
signal.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
 
int count=0;
void winHandle(int sig)
{
    printf("window change %d !\n",count);
    if(sig == SIGWINCH){ //如果窗口大小改变次数+1
        count++;
    }
 
    if(count ==3){//如果改变三次,程序结束。
        raise(SIGKILL);
    }
}
 
int main(int argc, const char *argv[])
{
    signal(SIGWINCH,winHandle);//信号SIGWINCH发生后执行winHandle函数
    while(1)
        sleep(5);
    return 0;
}

编译运行,拖到窗口,会看到打印信息,接收三次信号后程序结束:
在这里插入图片描述

图 1

实验2代码在alarm.c:路径为:11_Linux系统开发进阶\Linux系统编程_章节使用资料。
改变对 alarm定时到后SIGALRM信号的处理,

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
 
void timeOut(int sig)
{
    printf("topeet\n");
    alarm(2);
}
int main(int argc, const char *argv[])
{
    alarm(2);
    signal(SIGALRM,timeOut);
    while(1);
     
    return 0;
}

不调用signal()时,时间到后进程退出。
在这里插入图片描述

图 2

调用signal()改变对alarm超时信号的处理,时间到后再次定时,效果如下:
在这里插入图片描述

图 3

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值