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

Signal之掩码操作

作者头像
Taishan3721
发布2020-07-06 10:24:32
1.6K0
发布2020-07-06 10:24:32
举报
文章被收录于专栏:这里只有VxWorks这里只有VxWorks

欢迎关注VxWorks567

如转发 请标明出处

Kernel里,每个Task都有针对Signal的掩码(Mask)。掩码值为1表示拦截该Signal,即不处理Signal;掩码值为0表示会处理该Signal。而且默认情况下每个Task都会处理发给自己的Signal,只不过默认的处理方案是SIG_IGN(丢弃/忽略)。因此,要对Signal有所反应,就需要手动挂接Signal的处理机制了。今天看看Mask相关的操作

代码语言:javascript
复制

/* Signal的来源 */
#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

typedef unsigned long long sigset_t;

/* POSIX: 清空Signal掩码, 常用于初始化 */
int sigemptyset(sigset_t *pSet);

/* POSIX: 与sigemptyset()相反, 置所有Signal的bit位为1 */
int sigfillset(sigset_t *pSet);

/* POSIX: 在掩码pSet中添加signum */
int sigaddset(sigset_t *pSet, int signum);

/* POSIX: 在掩码pSet中去除signum */
int sigdelset(sigset_t *pSet, int signum);

/* POSIX: 在掩码pSet中是否包含signum */
int sigismember(sigset_t *pSet, int signum);

/* POSIX: 获取当前任务中阻塞的Signal */
int sigpending(sigset_t *pSet);

#define SIG_BLOCK   1
#define SIG_UNBLOCK 2
#define SIG_SETMASK 3
/* POSIX: 修改/查看掩码, 每个bit位表示一种Signal, 
 *                       1表示拦截, 0表示响应
 * pSet非空时,修改任务的Signal掩码
 * pOldSet非空时,查看任务原有的Signal掩码
 * how为修改方式
 *    SIG_BLOCK   - 在原有掩码上添加pSet
 *    SIG_UNBLOCK - 在原有源码上去除pSet
 *    SIG_SETMASK - 设置掩码为pSet
 */
int sigprocmask(int how, sigset_t *pSet, sigset_t *pOldSet);

/* 设置掩码
 * 类似于sigprocmask(SIG_SETMASK, mask, ...)
 * 只支持低32位
 * 不建议使用
 */
int sigsetmask(int mask);

/* 添加掩码
 * 类似于sigprocmask(SIG_BLOCK, mask, ...)
 * 只支持低32位
 * 不建议使用
 */
int sigblock(int mask);

跑个例子,看看掩码的效果

代码语言:javascript
复制

/*
 * Signal的使用
 * 公众号: VxWorks567
 */
#include <stdio.h>  /* printf()    */
#include <signal.h> /* sigaction() */
#include <unistd.h> /* pause()     */
#include <taskLib.h>/* taskName()  */

static void myHandler
(
int        sigNum,
siginfo_t *pInfo,
void      *pContext
    )
{
printf ("\n从%d接收到Signal(#%d), 并附带数值%d\n",
            pInfo->si_code, sigNum, pInfo->si_value.sival_int);
printf("任务%s的掩码是0x%016llx\n", taskName(0),
          ((struct sigcontext *)pContext)->sc_mask);
    }

void testSig()
{
struct sigaction newAction;
sigset_t newSet;
sigset_t oldSet;

    taskDelay(10);

/* 注册Signal处理函数到SIGUSR1 */
    newAction.sa_sigaction = myHandler;
    newAction.sa_mask  = 0;
    newAction.sa_flags = SA_SIGINFO;
    sigaction(SIGUSR1, &newAction, NULL);

/* 拦截SIGUSR2 */
    sigemptyset(&newSet);
    sigaddset(&newSet, SIGUSR2);
    sigprocmask(SIG_BLOCK, &newSet, &oldSet);
printf("\n原掩码是0x%016llx\n", oldSet);

/* 查看当前掩码 */
    sigprocmask(0, NULL, &newSet);
printf("当前掩码是0x%016llx\n", newSet);
    pause();
printf("任务%s被Signal激活\n", taskName(0));
    }

/* 发送SIGUSR1到testSig */
void giveSig(int tId)
{
union sigval value;
    value.sival_int = 100;
printf("发送Signal(#%d)到任务%s, 并附带数值%d\n", 
            SIGUSR1, taskName(tId), value.sival_int);
    sigqueue(tId, SIGUSR1, value);
    }

启动一个Task,挂接SIGUSR1的处理处理函数,并屏蔽SIGUSR2。执行效果如下

可以看到,设置掩码之前,不会拦截任何Signal,即原掩码是64个0

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

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

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

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

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