如何在睡眠时退出pthread时摆脱错误()?

时间:2016-03-03 18:29:47

标签: c linux multithreading sleep longjmp

首先,我想为这个令人困惑的头衔道歉。但这是我的问题:

我有一个主要功能,它产生另一个线程,它只是偶尔使用" sleep(3)"之间。

在main.c中,我有一个无限循环运行的循环。所以要取消程序,我必须按Ctrl + C.为了捕捉到这一点,我在主函数的开头添加了一个信号处理程序:

signal(SIGINT, quitProgram);

这是我的quitProgram函数:

void quitProgram() {  
    printf("CTRL + C received. Quitting.\n");  
    running = 0;  
    return;  
}

所以当running == 0时,循环就会离开。

这一切似乎都有效,至少在提到的线程开始之前。当线程启动后按Ctrl + C时,我收到一条奇怪的错误消息:

`*** longjmp causes uninitialized stack frame `***: ./cluster_control terminated  
======= Backtrace: =========  
/lib/i386-linux-gnu/libc.so.6(+0x68e4e)[0xb7407e4e]  
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x6b)[0xb749a85b]  
/lib/i386-linux-gnu/libc.so.6(+0xfb70a)[0xb749a70a]  
/lib/i386-linux-gnu/libc.so.6(__longjmp_chk+0x42)[0xb749a672]  
./cluster_control[0x8058427]  
[0xb76e2404]  
[0xb76e2428]  
/lib/i386-linux-gnu/libc.so.6(nanosleep+0x46)[0xb7454826]  
/lib/i386-linux-gnu/libc.so.6(sleep+0xcd)[0xb74545cd]  
./cluster_control[0x804c0e6]  
./cluster_control[0x804ae61]  
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb73b8a83]  
./cluster_control[0x804a331]  

When I try to debug it using gdb I get the following:

    `(gdb) where
    `#0  0xb7fdd428 in __kernel_vsyscall ()
    `#1  0xb7d4f826 in nanosleep () at ../sysdeps/unix/syscall-template.S:81
    `#2  0xb7d4f5cd in __sleep (seconds=0) at ../sysdeps/unix/sysv/linux/sleep.c:137
    `#3  0x0804c0e6 in master_main (mastBroad_sock=3, workReady_ptr=0xbffff084) at master.c:150
    `#4  0x0804ae61 in main () at main.c:84

master.c中的第150行是这样的:
     睡眠(PING_PERIOD);

所以我猜测发生了什么:当master_main线程正在休眠时,主线程正在退出,这导致了错误。但是:我该如何解决这个问题?是否有更好的方法让master_main线程每隔几秒运行一次?或者在master_man仍然处于睡眠状态时阻止主线程退出?

我尝试使用互斥锁,但它没有工作(在master_main休眠之前锁定互斥锁并在之后解锁它并且退出的主线程需要该互斥锁退出)。

另外,我通过一个指针从main传递给main_master。所以我会将main_master的状态设置为"退出"在退出主要方法之前,但也没有。

还有其他想法吗?我正在运行linux和编程语言是C99。

更新1 对不起伙计们,我想我给了你错误的信息。引起麻烦的方法甚至不在线程内部。这是我主要方法的摘录:

int main() {
[...]
signal(SIGINT, quitProgram);
while (running)
{
    // if system is the current master
if (master_i)
{
            master_main(mastBroad_sock, &workReady_condMtx);
            pthread_mutex_lock(&(timeCount_mtx_sct.mtx));
            master_i = 0;
            pthread_mutex_unlock(&(timeCount_mtx_sct.mtx));
        }
    [...]
}
return 0;
}

还有master_main的摘录,我猜是问题。

int master_main(int mastBroad_sock, struct cond_mtx *workReady_ptr) {
[...]
     while (master_i)
     {
          // do something
          sleep(5);   // to perform this loop only every 5 seconds, this is line 150 in master.c
     }
}

更新2 忘了添加在main.c中捕获Ctrl + C的代码:

void quitProgram() {
   printf("CTRL + C received. Quitting.\n");
   running = 0;
   return;
}

1 个答案:

答案 0 :(得分:1)

最简单的解决方案是使用一个全局标志来告诉线程程序正在关闭,因此当主函数想要关闭时,它会设置标志,然后等待线程终止。 见Joining and Detaching Threads。根据线程的作用,您可能还需要查看Condition Variables