我是靠谱客的博主 明理书包,最近开发中收集的这篇文章主要介绍POSIX线程使用signal模拟“中断“处理流程一. 中断/信号处理流程示意图二.POSIX线程信号处理流程说明三.POSIX线程信号API和数据结构3.sigemptyset四.示例程序,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一. 中断/信号处理流程示意图

二.POSIX线程信号处理流程说明

1. 与中断handler对应的,信号也有handler。每个特定的中断对应一个handler,每个特定的信号也对应一个handler。

2. 中断通过硬件或者int指令等方式触发handler执行,信号通过pthread_kill向某个线程发送信号触发handler执行。该线程收到信号后,会打断当前执行流并跳转到信号handler执行,之后返回到当前执行流。

三.POSIX线程信号API和数据结构

1.sigaction

sigaction ———— 查询或设置信号处理方式
(1)头文件
    #include<signal.h>
(2)函数原型
    int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);
    sigaction()会根据参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILL和SIGSTOP以外的所有信号。
(3)数据结构
    struct sigaction
    {
       void (*sa_handler) (int);
       sigset_t sa_mask;
       int sa_flags;
       void (*sa_restorer) (void);
    }
sa_handler此参数和signal()的参数handler相同,代表新的信号处理函数,其他意义请参考signal()。
sa_mask 用来设置在处理该信号时暂时将sa_mask 指定的信号搁置。
sa_restorer 此参数没有使用。
sa_flags 用来设置信号处理的其他相关操作,下列的数值可用。

2.sigfillset

sigfillset ———— 将所有信号加入此信号集
(1)头文件
    #include<signal.h
(2)函数原型
    int sigfillset(sigset_t * set);
    sigfillset()用来 将参数set信号集初始化,然后把所有的信号加入到此信号集里。

3.sigemptyset

sigemptyset ———— 初始化信号集
(1)头文件
    #include<signal.h>
(2)函数原型
    int sigemptyset(sigset_t *set);
    sigemptyset()用来将参数set信号集初始化并清空。

4.pthread_sigmask

pthread_sigmask ———— 更改或检查调用线程的信号掩码
(1)头文件
    #include <pthread.h>
    #include<signal.h>
(2)函数原型
    int pthread_sigmask(int how, const sigset_t *new, sigset_t *old);
 
how用来确定如何更改信号组,可以为以下值之一:
SIG_BLOCK:向当前的信号掩码中添加new,其中new表示要阻塞的信号组。
SIG_UNBLOCK:向当前的信号掩码中删除new,其中new表示要取消阻塞的信号组。
SIG_SETMASK:将当前的信号掩码替换为new,其中new表示新的信号掩码。

5.pthread_kill

pthread_kill ———— 向线程发送信号
(1) 头文件
    #include <pthread.h>
    #include<signal.h>
(2)函数原型
    int pthread_kill(thread_t tid, int sig);
    pthread_kill() 将信号sig发送到由tid指定的线程。tid所指定的线程必须与调用线程在同一个进程中。

四.示例程序

#include <pthread.h>
#include <stdio.h>
#include <sys/signal.h>

#define NUMTHREADS 3
void sighand(int signo);

void *threadfunc(void *parm)
{
    pthread_t             tid = pthread_self();
    int                   rc;

    printf("Thread %u entered/n", tid);
    rc = sleep(30); /* 若有信号中断则返回剩余秒数 */
    printf("Thread %u did not get expected results! rc=%d/n", tid, rc);
    return NULL;
}

void *threadmasked(void *parm)
{
    pthread_t             tid = pthread_self();
    sigset_t              mask;
    int                   rc;

    printf("Masked thread %lu entered/n", tid);

    sigfillset(&mask); /* 将所有信号加入mask信号集 */

    /* 向当前的信号掩码中添加mask信号集 */
    rc = pthread_sigmask(SIG_BLOCK, &mask, NULL);
    if (rc != 0)
    {
        printf("%d, %s/n", rc, strerror(rc));
        return NULL;
    }

    rc = sleep(15);
    if (rc != 0)
    {
        printf("Masked thread %lu did not get expected results! rc=%d /n", tid, rc);
        return NULL;
    }
    printf("Masked thread %lu completed masked work/n", tid);
    return NULL;
}

int main(int argc, char **argv)
{
    int                     rc;
    int                     i;
    struct sigaction        actions;
    pthread_t               threads[NUMTHREADS];
    pthread_t               maskedthreads[NUMTHREADS];

    printf("Enter Testcase - %s/n", argv[0]);
    printf("Set up the alarm handler for the process/n");

    memset(&actions, 0, sizeof(actions));
    sigemptyset(&actions.sa_mask); /* 将参数set信号集初始化并清空 */
    actions.sa_flags = 0;
    actions.sa_handler = sighand;

    /* 设置SIGALRM的处理函数 */
    rc = sigaction(SIGALRM,&actions,NULL);

    printf("Create masked and unmasked threads/n");
    for(i=0; i<NUMTHREADS; ++i)
    {
        rc = pthread_create(&threads[i], NULL, threadfunc, NULL);
        if (rc != 0)
        {
            printf("%d, %s/n", rc, strerror(rc));
            return -1;
        }

        rc = pthread_create(&maskedthreads[i], NULL, threadmasked, NULL);
        if (rc != 0)
        {
            printf("%d, %s/n", rc, strerror(rc));
            return -1;
        }
    }

    sleep(3);
    printf("Send a signal to masked and unmasked threads/n");

     /* 向线程发送SIGALRM信号 */
    for(i=0; i<NUMTHREADS; ++i)
    {
        rc = pthread_kill(threads[i], SIGALRM);
        rc = pthread_kill(maskedthreads[i], SIGALRM);
    }

    printf("Wait for masked and unmasked threads to complete/n");
    for(i=0; i<NUMTHREADS; ++i) {
        rc = pthread_join(threads[i], NULL);
        rc = pthread_join(maskedthreads[i], NULL);
    }

    printf("Main completed/n");
    return 0;
}

void sighand(int signo)
{
    pthread_t             tid = pthread_self();

    printf("Thread %lu in signal handler/n", tid);
    return;
}

参考:

POSIX 线程 – pthread_sigmask - Prayer - C++博客 (cppblog.com)

最后

以上就是明理书包为你收集整理的POSIX线程使用signal模拟“中断“处理流程一. 中断/信号处理流程示意图二.POSIX线程信号处理流程说明三.POSIX线程信号API和数据结构3.sigemptyset四.示例程序的全部内容,希望文章能够帮你解决POSIX线程使用signal模拟“中断“处理流程一. 中断/信号处理流程示意图二.POSIX线程信号处理流程说明三.POSIX线程信号API和数据结构3.sigemptyset四.示例程序所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部