Прежде всего, я хотел бы извиниться за запутанный заголовок. Но вот мой вопрос:
У меня есть основная функция, которая порождает другой поток, который время от времени работает только с «сном (3)» между ними.
Внутри main.c у меня есть цикл while, который работает бесконечно. Итак, чтобы отменить программу, я должен нажать 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
Строка 150 в master.c такова:
sleep(PING_PERIOD);
Итак, я предполагаю, что происходит: основной поток завершается, пока поток master_main спит, и это вызывает ошибку. Но: Как я могу это исправить? Есть ли лучший способ запускать поток master_main каждые несколько секунд? Или предотвратить выход основного потока, пока master_man все еще спит?
Я пытался использовать мьютекс, но это не сработало (заблокировал мьютекс до того, как master_main спит, и разблокировал его после этого, а выходящий основной поток нуждался в этом мьютексе для выхода).
Кроме того, я передал указатель с main на main_master с состоянием. Поэтому я бы установил состояние main_master на «выход» перед выходом из основного метода, но это тоже не сработало.
Так есть еще идеи? У меня линукс и язык программирования 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 Забыли добавить код, который ловит Ctrl+C внутри main.c:
void quitProgram() {
printf("CTRL + C received. Quitting.\n");
running = 0;
return;
}