前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Signal之基本操作

Signal之基本操作

作者头像
Taishan3721
发布2020-07-01 14:59:54
1.6K0
发布2020-07-01 14:59:54
举报
文章被收录于专栏:这里只有VxWorks这里只有VxWorks

注册

要想使用Signal,首先需要注册Signal的处理函数,就像中断的ISR。最基本的方法是POSIX定义的sigaction()

代码语言:javascript
复制
typedef unsigned long long sigset_t;
union sigval
    {
    int   sival_int;
    void *sival_ptr;
    };
typedef struct _Siginfo
    {
    int   si_signo;
    int   si_code;
    union sigval si_value;
    } siginfo_t;
struct sigaction
    {
    union
        {
        void (*__sa_handler)(int);
        void (*__sa_sigaction)(int, siginfo_t *, void *);
        } sa_u;
    #define  sa_handler sa_u.__sa_handler
    #define  sa_sigaction sa_u.__sa_sigaction
    sigset_t sa_mask;
    int      sa_flags;
    };
/*
 * POSIX定义的Signal处理函数的安装机制
 * sig   - Signal number
 * pAct  - 新的处理函数支持1个参数或3个参数
 * pOact - 获得之前的处理函数
 */
int sigaction
    (
    int               sig,
    struct sigaction *pAct,
    struct sigaction *pOact
    );

或者使用简化一些的sigvec()

代码语言:javascript
复制
typedef unsigned long long sigset_t;
struct sigvec
    {
    void   (*sv_handler)(int);
    sigset_t sv_mask;
    int      sv_flags;
    };
/*
 * 简化一些的安装机制
 * sig   - Signal number
 * pVec  - 新的处理函数支持1个参数
 * pOvec - 获得之前的处理函数
 */
int sigvec
    (
    int            sig,
    struct sigvec *pVec,
    struct sigvec *pOvec
    );

而最简单的是直接使用signal()

代码语言:javascript
复制
/*
 * 最简单的安装机制
 * sig      - Signal number
 * pHandler - 处理函数支持1个参数
 * 返回值是之前的处理函数
 */
void (*signal(int sig, void(*pHandler)(int)))(int);

等待

注册了Signal之后,这个任务就可以去忙自己的工作了。当相应的Signal被触发后,就会执行注册的函数,所以这个流程是异步的。那如果想同步操作呢?该任务就需要将自己阻塞,等待Signal将其唤醒

最简单的方法是pause()

代码语言:javascript
复制
/*
 * 当前任务进入阻塞状态
 * 等待Signal激活
 */
int pause(); /* POSIX */

但有时候不希望被某些Signal打扰,那就使用sigsuspend()将它们屏蔽掉

代码语言:javascript
复制
typedef unsigned long long sigset_t;
/*
 * 功能与pause()类似
 * 但忽略pSet指定的Signal
 */
int sigsuspend /* POSIX */
    (
    sigset_t *pSet
    );

甚至有时候不需要使用处理函数

代码语言:javascript
复制
/*
 * 当前任务进入阻塞状态
 * 等待pSet指定的Signal激活
 * 通常使用sigprocmask()屏蔽其它Signal
 *
 * 由pSig返回接收到的Signal number
 * 并忽略相应Signal的处理函数
 */
int sigwait /* POSIX */
    (
    sigset_t *pSet,
    int      *pSig
    );

#define SI_SYNC     0 /* (Not posix) gernerated by hardware */
#define SI_USER    -1 /* signal from kill() function */
#define SI_QUEUE   -2 /* signal from sigqueue() function */
#define SI_TIMER   -3 /* signal from expiration of a timer */
#define SI_ASYNCIO -4 /* signal from completion of async I/O */
#define SI_MESGQ   -5 /* signal from arrival of a message */
#define SI_CHILD   -6 /* signal from child, stopped or terminated */
#define SI_KILL    SI_USER
/*
 * 功能与sigwait()类似
 * 由pInfo->si_signo返回接收到的Signal number
 * 由pInfo->si_code返回Signal的触发源
 * 由pInfo->si_value返回Queued Signal的Value
 */
int sigwaitinfo
    (
    sigset_t  *pSet,
    siginfo_t *pInfo
    );

typedef unsigned long time_t;
struct timespec
    {
    time_t tv_sec;
    long   tv_nsec;
    };
/*
 * 功能与sigwait()类似
 * 由pTimeout设置超时机制
 */
int sigtimedwait
    (
    sigset_t        *pSet,
    siginfo_t       *pInfo,
    struct timespec *pTimeout
    );

触发

那如何产生Signal呢?简单的方法是raise()和kill()

代码语言:javascript
复制
/*
 * 向自己发送一个Signal
 */
int raise
    (
    int sig
);
/*
 * 向tid发送一个Signal
 */
int kill
    (
    TASK_ID tid,
    int     sig
);

复杂一点的函数是sigqueue()

代码语言:javascript
复制

/*
 * 向tid发送一个可以排队的Signal
 * 并附带一个value
 */
int sigqueue
    (
    TASK_ID      tid,
    int          sig,
    union sigval value
);

还有一个特殊的封装 - alarm(),详情见《Utility之定时(2)

代码语言:javascript
复制
/* 向自己发送SIGALRM */
unsigned int alarm /* POSIX */
    (
    unsigned int secs
    );

最后跑一个最简单的小栗子

我是泰山,专注VX好多年!

一起学习,共同进步!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 这里只有VxWorks 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档