在c中终止信号处理程序的执行
to terminate the execution of signal handler in c
我目前正在从事涉及使用 SPI 通信将 ADC 与 Ras.-Pi 连接的项目。在项目中,我使用定时器控制 SPI 的初始化,然后启动信号处理程序。在信号处理程序中,SPI 传输发生并且值存储在变量中,我在线程中访问这个变量并将接收到的值存储在数组中。
代码运行但程序永远不会从信号处理程序中出来。我希望处理程序在每次处理值时跳转到线程以存储接收到的值。
谁能给我指点靠谱的。
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);
如果我理解正确,您希望每 x 个进程执行时间(而不是挂钟时间,因为 SIGVTALRM 暗示 ITIMER_VIRTUAL 进行一次“状态更新”我)。
最安全、最简单的方法是accept a pending signal,而不是将信号传递给信号处理程序。
在产生任何线程之前,使用 pthread_sigmask
到 SIG_BLOCK 至少 SIGVTALRM。所有新线程都将继承该信号掩码。然后,产生你的状态线程,分离,它设置一个间隔虚拟时钟定时器和循环,等待接受 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
}
放在一边
可以使用信号处理程序正确地做到这一点。
它非常细微,细微差别很重要。您可能应该知道 sigaction
is preferred over signal
and why. 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
,以及您为什么会关心。在信号处理程序中可以安全地调用非常非常少的函数。在我看来,sigemptyset(&sa.sa_mask)
有点货物文化,你几乎肯定想要在任何相应的处理程序中使用 完整 掩码。
即便如此,也不值得。接受信号是比传递更高级的用法:您可以在安全的时间和地点对信号做出反应。
我目前正在从事涉及使用 SPI 通信将 ADC 与 Ras.-Pi 连接的项目。在项目中,我使用定时器控制 SPI 的初始化,然后启动信号处理程序。在信号处理程序中,SPI 传输发生并且值存储在变量中,我在线程中访问这个变量并将接收到的值存储在数组中。 代码运行但程序永远不会从信号处理程序中出来。我希望处理程序在每次处理值时跳转到线程以存储接收到的值。 谁能给我指点靠谱的。
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);
如果我理解正确,您希望每 x 个进程执行时间(而不是挂钟时间,因为 SIGVTALRM 暗示 ITIMER_VIRTUAL 进行一次“状态更新”我)。
最安全、最简单的方法是accept a pending signal,而不是将信号传递给信号处理程序。
在产生任何线程之前,使用 pthread_sigmask
到 SIG_BLOCK 至少 SIGVTALRM。所有新线程都将继承该信号掩码。然后,产生你的状态线程,分离,它设置一个间隔虚拟时钟定时器和循环,等待接受 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
}
放在一边
可以使用信号处理程序正确地做到这一点。
它非常细微,细微差别很重要。您可能应该知道 sigaction
is preferred over signal
and why. 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
,以及您为什么会关心。在信号处理程序中可以安全地调用非常非常少的函数。在我看来,sigemptyset(&sa.sa_mask)
有点货物文化,你几乎肯定想要在任何相应的处理程序中使用 完整 掩码。
即便如此,也不值得。接受信号是比传递更高级的用法:您可以在安全的时间和地点对信号做出反应。