简体   繁体   English

终止 c 中信号处理程序的执行

[英]to terminate the execution of signal handler in c

i am currently working on project involving the interfacing of an ADC with Ras.-Pi using SPI communication.我目前正在从事涉及使用 SPI 通信将 ADC 与 Ras.-Pi 接口的项目。 In the project I am controlling the initialisation of SPI using a timer, which then initiates a signal handler.在项目中,我使用定时器控制 SPI 的初始化,然后启动信号处理程序。 In the signal handler the SPI transmission takes place and value is being stored in a variable, this variabler i am accesing in a thread and storing the recieved value in an array.在信号处理程序中,发生 SPI 传输并将值存储在一个变量中,我在一个线程中访问这个变量并将接收到的值存储在一个数组中。 The code runs but the program never comes out of the signal handler.代码运行,但程序永远不会从信号处理程序中出来。 I want the handler to jump to the thread to store the recieved value everytime it processes a value.我希望处理程序在每次处理值时跳转到线程以存储收到的值。 Can someone point me to something reliable.有人可以指点我一些可靠的东西。

void getSPIvalues(){ // A new Thread which runs parallel and get the values from ADC over SPI
    printf("inside thread function\n");
    timer_useconds(100, 1);
    spiValues[i] = rawData;
    printf("from thread, value = %d\n", spiValues[i]);
    i++;
}

void signalHandler(int sig){ 
    printf("inside handler function\n");
    PWMGenerate(0, 26, 2);  //Zyklus = 960 ns, Freuquency = 1,1 MHz, duty clycle= 8 %
    char data[2];
    bcm2835_spi_transfern(data, sizeof(data));
    rawData = (int)(data[0] << 8 | data[1]);
    bcm2835_gpio_write(PIN, LOW);
}

    //Handler Installation
    memset(&sa, 0, sizeof(sa));
    sigemptyset(&sa.sa_mask);
    sa.sa_handler = &signalHandler;
    sigaction(SIGVTALRM, &sa, NULL);

If I understand correctly, you want a "status update" every x useconds of process execution (rather than of wall clock time, as SIGVTALRM implies ITIMER_VIRTUAL to me).如果我理解正确,您需要每x u 秒的进程执行“状态更新”(而不是挂钟时间,因为 SIGVTALRM 对我来说意味着ITIMER_VIRTUAL )。

The safest, simplest way to do this will be to accept a pending signal , instead of delivering that signal to a signal handler.最安全、最简单的方法是接受一个挂起的信号,而不是将该信号传递给信号处理程序。

Before spawning any threads, use pthread_sigmask to SIG_BLOCK at least SIGVTALRM.在产生任何线程之前,使用pthread_sigmask到 SIG_BLOCK 至少 SIGVTALRM。 All new threads will inherit that signal mask.所有新线程都将继承该信号掩码。 Then, spawn your status thread, detached, which sets an intervalic virtual clock timer and loops, waiting to accept VTALRM:然后,产生你的状态线程,分离,它设置一个间隔的虚拟时钟计时器和循环,等待接受 VTALRM:

static void *
my_status_thread(void *ignored) { // spawn me with VTALRM blocked
    sigset_t desired;             // for me and everyone else!

    sigemptyset(&desired);
    sigaddset(&desired, SIGVTALRM);

    set_itimer_virtual(100, 1);  // setitimer()

    while (1) {
        int s;
        (void)sigwait(&desired, &s);
        // we got VTALRM, pull the data
        PWMGenerate(...);
        ....
        printf("value is %d\n", ...);
    }

    return NULL; // not reached
}

Aside在旁边

It is possible to do this correctly with signal handlers.可以使用信号处理程序正确执行此操作。

It's quite nuanced, and the nuances matter.它非常微妙,细微差别很重要。 You should probably be aware that sigaction is preferred over signal and why.您可能应该知道sigaction优于signal以及为什么。 That signal disposition (a registered "handler" or "behavior") is a global process attribute, though signal delivery per se and signal masking are per-thread.该信号处置(注册的“处理程序”或“行为”)是全局进程属性,尽管信号传递本身和信号屏蔽是每个线程的。 That sig_atomic_t doesn't necessarily mean volatile , and why you'd care.sig_atomic_t并不一定意味着volatile ,以及为什么你会关心。 That very, very few functions can be safely invoked within a signal handler.在信号处理程序中可以安全地调用非常非常少的函数。 That sigemptyset(&sa.sa_mask) is, in my opinion, a bit cargo-culty, and you almost certainly want a full mask inside any consequential handlers.在我看来,那个sigemptyset(&sa.sa_mask)有点像货物,你几乎可以肯定在任何后续处理程序中都需要一个完整的掩码。

Even then, it's just not worth it.即使那样,这也不值得。 Signal acceptance is a superior idiom to delivery: you react to signals when and where it is safe for you to do so.信号接受是一种优于传递的习惯用法:您在安全的时间和地点对信号做出反应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM