0
static timer_t timer;
void timer_handle(union sigval sig)
{
    printf("pthread=%lu ptr=%p\n", pthread_self(), sig.sival_ptr);
}
void x_add_timer(void)
{
    struct sigevent event;
    struct itimerspec ts = {{0, 0}, {0, 10000}};            
    memset(&event, 0, sizeof(event));
    event.sigev_notify = SIGEV_THREAD;
    event.sigev_notify_function = timer_handle;
    timer_create(CLOCK_MONOTONIC, &event, &timer);    
    timer_settime(timer, 0, &ts, NULL);     

}
void x_del_timer(void)
{
    timer_delete(timer);
}
int main()
{
    int i;
    struct timespec t = {0, 8000};  
    for (i = 0; i < 100; i++) {
        x_add_timer();
        nanosleep(&t, NULL);
        x_del_timer();
    }     
    return 0;
}


我是 Linux 编程的新手。我正在学习 glibc 计时器。但我遇到了一个奇怪的问题。
我编写上面的代码并使用mips64-octeon-linux-gnu-gcc进行编译。 但是在设备上运行时 有时会
出现Segmentation fault代码有什么问题吗?非常感谢。

核心转储是

Program terminated with signal 11, Segmentation fault.
[New process 16487]
[New process 16443]
[New process 16444]
#0  0x0000005558155568 in main_arena () from /lib64/libc.so.6

完整的回溯是

Thread 3 (process 16444):
#0  0x00000055580c839c in clone () from /lib64/libc.so.6
No symbol table info available.
#1  0x0000005558176d38 in do_clone () from /lib64/libpthread.so.0
No symbol table info available.
#2  0x0000005558177260 in pthread_create@@GLIBC_2.2 ()
   from /lib64/libpthread.so.0
No symbol table info available.
#3  0x0000005557fb8cdc in timer_helper_thread () from /lib64/librt.so.1
No symbol table info available.
#4  0x0000005558177cec in start_thread () from /lib64/libpthread.so.0
No symbol table info available.
#5  0x00000055580c83ec in __thread_start () from /lib64/libc.so.6
No symbol table info available.

Thread 2 (process 16443):
#0  0x000000555808f0e4 in nanosleep () from /lib64/libc.so.6
No symbol table info available.
#1  0x000000555808edfc in sleep () from /lib64/libc.so.6
No symbol table info available.
#2  0x0000000120000f54 in main () at hello.c:53
        i = 100
        t = {tv_sec = 0, tv_nsec = 8000}

Thread 1 (process 16487):
#0  0x0000005558155568 in main_arena () from /lib64/libc.so.6
No symbol table info available.
#1  0x0000005557fb8d5c in timer_sigev_thread () from /lib64/librt.so.1
No symbol table info available.
#2  0x0000005558177cec in start_thread () from /lib64/libpthread.so.0
No symbol table info available.
#3  0x00000055580c83ec in __thread_start () from /lib64/libc.so.6
No symbol table info available.
4

1 回答 1

0

你有一个明确的比赛条件。

在更高的速度(更短的睡眠时间10us)下,您的

nanosleep(&t, NULL); 

其中 t 设置为timespec {0, 8000};,在“计时器”触发之前返回。

因此x_del_timer()andtimer_handle()以错误的顺序发生。

增加 nanosleep() 时间以降低此概率。

glibc如果对计时器 API 的支持OCTEON/mips64存在极端情况,我不会感到惊讶。

于 2016-07-21T21:14:38.217 回答