2016-12-29 2 views
5

Согласно Oracle Multithreaded Programming Guide, fork() должен быть безопасным для использования внутри обработчиков сигналов. Но мой процесс застрял внутри обработчика сигнала с к следующей обратной трассировке:Асинхронный сигнал безопасности вилки()

#0 __lll_lock_wait_private() at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95 
#1 0x00007f86e6a9990d in _L_lock_48() from /lib/x86_64-linux- gnu/libc.so.6 
#2 0x00007f86e6a922ec in ptmalloc_lock_all() at arena.c:242 
#3 0x00007f86e6ad5e82 in __libc_fork() at ./nptl/sysdeps/unix/sysv/linux/x86_64/../fork.c:95 
#4 0x00007f86e7d9f125 in __fork() at ./nptl/sysdeps/unix/sysv/linux/pt-fork.c:25 
.... 
#7 signal handler called 

Так, как malloc не безопасно быть использованы в обработчике сигнала, как fork может быть?

Заранее спасибо.

+1

Это, вероятно, не 'fork', это проблема, но * ваш * код, который следует за вызовом. (Обратите внимание, что трассировки стека могут вводить в заблуждение, если у вас есть сломанный обработчик сигналов.) –

+1

Дайте нам достаточно кода для репликации проблемы. Скорее всего, в процессе подготовки этого кода вы обнаружите проблему - это будет то, что вы удалили, что заставило проблему уйти. –

+0

, но замок находится внутри fork() - так как это может быть связано с кодом, который приходит после этого? –

ответ

3

Это теперь listed as a bug by RedHat:

Bug 1422161 - Glibc: вилка не асинхронный сигнала безопасного

...

+++ Эта ошибка была изначально создана как клон Bug # 1422159 +++

POSIX требует, чтобы вилка была безопасна для асинхронного сигнала. Наш текущий реализация нет.

-2

fork() начнет новый процесс, скопировав часть памяти родителей, но оба они являются отдельными процессами. Поэтому безопасно использовать встроенный обработчик сигнала. Ниже приведен пример бегущего ребенка ....

#include <stdio.h> 
#include <unistd.h> 
#include <signal.h> 
#include <stdlib.h> 

int SHOULD_RUN = 1; 
void int_sig_handler(int signal){ 
     printf("SIG_INT\n"); 
     if(fork() == 0){ 
       // child code 
       printf("I am Child"); 
       //signal(SIGINT, int_sig_handler); 
       SHOULD_RUN = 1; 
       while(SHOULD_RUN){ 
         printf("I am Running Still...\n"); 
         sleep(1); 
       } 
       exit(0); 
     }else{ 
       // parent code 
       printf("parent"); 
     } 
     SHOULD_RUN = 0; 
} 


int main(int argc, const char *argv[]){ 
     signal(SIGINT, int_sig_handler); 
     while(SHOULD_RUN){ 
       sleep(1); 
     } 
     return 0; 
}