Как избавиться от ошибки при выходе из pthread во время сна()?

115
12

прежде всего, я хотел бы извиниться за запутанный титул. Но вот мой вопрос:

У меня есть основная функция, которая порождает другой поток, который время от времени работает только с "sleep (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 такова:
сна (PING_PERIOD);

Итак, я догадываюсь, что происходит: основной поток выходит, пока поток master_main спал, и это вызывает ошибку. Но: Как я могу это исправить? Есть ли лучший способ, чтобы поток master_main выполнялся каждые несколько секунд? Или для предотвращения выхода основного потока, пока мастер-мастер все еще находится во сне?

Я попытался использовать мьютексы, но это не сработало (блокировка мьютекса до того, как master_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 Забыл добавить код, который ловит Ctrl + C внутри main.c:

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

спросил(а) 2016-03-03T21:29:00+03:00 4 года, 4 месяца назад
1
Решение
55

Самое простое решение, которое приходит на ум, - иметь глобальный флаг, который сообщает потоку, что программа выключается, и поэтому, когда основная функция хочет завершить работу, она устанавливает флаг, а затем ждет завершения потока. См. Присоединение и отсоединение потоков. В зависимости от того, что делает поток, вы также можете взглянуть на переменные состояния.

ответил(а) 2016-03-03T21:48:00+03:00 4 года, 4 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема