有人可以解释为什么在5-7次迭代后,定时器会因SIGSEGV而失败?
在两种情况下都会发生:同步和不同步。 操作系统是Ubuntu 15.04,Ubuntu GLIBC 2.21-0ubuntu4。
void timer_thread (sigval signal_value) {
printf ("Timer callback!\n");
}
int main(int argc, char* argv[]) {
const int TIMER_COUNT = 300;
for (int i = 0; i < 10000; i++) {
int status = 0;
timer_t timer_id[TIMER_COUNT] = {};
memset(&timer_id[0], 0, sizeof(timer_t)*TIMER_COUNT);
for (int j = 0; j < TIMER_COUNT; j++) {
struct itimerspec ts = {};
struct sigevent se = {};
memset(&ts, 0, sizeof(itimerspec));
memset(&se, 0, sizeof(sigevent));
se.sigev_notify = SIGEV_THREAD;
se.sigev_value.sival_int = j;
se.sigev_notify_function = timer_thread;
// Specify a repeating timer that fires each 100000 nanosec.
memset(&ts, 0, sizeof(ts));
ts.it_value.tv_nsec = 100000;
ts.it_interval.tv_nsec = 100000;
status = timer_create(CLOCK_REALTIME, &se, &timer_id[j]);
assert(!status && "Create timer");
status = timer_settime(timer_id[j], 0, &ts, 0);
assert(!status && "Set timer");
}
for (int j = 0; j < TIMER_COUNT; j++) {
usleep(100);
//stop and delete
status = timer_delete(timer_id[j]);
assert(!status && "Fail delete timer");
}
}
printf("Success!\n");
return 0;
}
GDB回溯:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 __pthread_create_2_1 (newthread=newthread@entry=0x7f00e9817e28, attr=attr@entry=0x11c47e8, start_routine=start_routine@entry=0x7f00e93f6eb0 <timer_sigev_thread>, arg=<optimized out>)
at pthread_create.c:711
711 pthread_create.c: No such file or directory.
(gdb) bt
#0 __pthread_create_2_1 (newthread=newthread@entry=0x7f00e9817e28, attr=attr@entry=0x11c47e8, start_routine=start_routine@entry=0x7f00e93f6eb0 <timer_sigev_thread>, arg=<optimized out>)
at pthread_create.c:711
#1 0x00007f00e93f6e7a in timer_helper_thread (arg=<optimized out>) at ../sysdeps/unix/sysv/linux/timer_routines.c:125
#2 0x00007f00e91db6aa in start_thread (arg=0x7f00e9818740) at pthread_create.c:333
#3 0x00007f00e866feed in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
构建命令行:/usr/bin/c++ -lrt -lpthread -g ./main.cc
答案 0 :(得分:0)
以下代码实际运行,不会崩溃,干净地编译
注意每个计时器的扩展时间间隔,这是大约300个计时器有时间调用printf()并返回。
BTW:在信号处理程序中调用printf()
是一个非常糟糕的主意
#include <stdio.h> // printf()
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <signal.h>
#include <time.h>
#include <unistd.h> // sleep()
#include <string.h> // memset()
#define TIMER_COUNT (300)
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
void timer_thread (union sigval sigev_value)
{
(void)sigev_value;
static int count = 0;
count++;
fprintf ( stdout, "Timer callback count: %d\n", count);
}
int main( void )
{
timer_t timer_id[TIMER_COUNT];
memset(timer_id, '\0', sizeof(timer_t)*TIMER_COUNT);
struct itimerspec ts;
struct sigevent se;
for (size_t j = 0; j < TIMER_COUNT; j++)
{
memset(&ts, '\0', sizeof(struct itimerspec));
memset(&se, '\0', sizeof(struct sigevent));
se.sigev_notify = SIGEV_THREAD;
se.sigev_value.sival_int = (int)j;
se.sigev_notify_function = timer_thread;
// Specify a repeating timer that fires each 2 second.
ts.it_interval.tv_sec = 2;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = ts.it_interval.tv_sec;
ts.it_value.tv_nsec = ts.it_interval.tv_nsec;
if( -1 == timer_create(CLOCK_REALTIME, &se, &timer_id[j]) )
errExit( "timer_create failed" );
if( -1 == timer_settime(timer_id[j], 0, &ts, NULL) )
errExit("timer_settime failed");
}
sleep(10);
for (int j = 0; j < TIMER_COUNT; j++)
{
//stop and delete
fprintf( stdout, "stopping timer: %d, with ID: %lu\n", j, (size_t)timer_id[j]);
ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
if( -1 == timer_settime( timer_id[j], 0, &ts, NULL) )
errExit("timer_settime (to disable timer) failed" );
fprintf( stdout, "deleting timer: %d, with ID: %lu\n", j, (size_t)timer_id[j]);
if( -1 == timer_delete(timer_id[j]) )
errExit("timer_delete failed" );
}
printf("Success!\n");
return 0;
} // end function: main