linux - 使用 glibc 定时器时出现段错误

标签 linux timer glibc

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进行编译。
但是在设备上运行时有时会发生段错误
代码有什么问题吗? 非常感谢。

核心转储是

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.

最佳答案

那里有一个明确的竞争条件。

以更高的速度(更短的 sleep 时间 10us),您的

nanosleep(&t, NULL); 

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

因此,x_del_timer()timer_handle() 发生的顺序错误。

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

如果 glibcOCTEON/mips64 的支持存在定时器 API 的极端情况问题,我不会感到惊讶。

关于linux - 使用 glibc 定时器时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16458394/

相关文章:

c# - 振动直到消息框关闭 Windows Phone 7

ios - getTimeElapsed 在 Swift 中使用 NSTimer

android-ndk - 如何将libc添加到android应用程序中?

编译单独的内核模块 (Debian/Ubuntu)

c - 第二个线程无法通过 C/C++/linux 中线程 1 发送的消息队列接收消息

JavaScript 定时器循环

c - dbus_g_proxy_call 到 freedesktop "Get"方法给出错误预期类型 gchararray,得到类型代码 'v'

c - 不同的行为取决于架构

linux - 即使安装后也没有名为 numpy 的模块

linux - RPM 包中 SPEC 文件中 1%{?dist} 的含义是什么