O que acontece com um processo Linux multithread se ele recebe um sinal?

20

Se um processo Unix (Posix) receber um sinal, um manipulador de sinal será executado.

O que acontecerá com ele em um processo multithread? Qual thread recebe o sinal?

Na minha opinião, a API de sinal deve ser estendida para lidar com isso (ou seja, o segmento do manipulador de sinal deve poder ser determinado), mas, procurando informações na rede, só encontrei chamas de um ano na lista de discussão do kernel do linux e em fóruns diferentes. Pelo que entendi, o conceito de Linus diferia do padrão Posix, e primeiro foi criada uma camada compat, mas agora o Linux segue o modelo posix.

Qual é o estado atual?

peterh - Restabelecer Monica
fonte
3
Duplicado de stackoverflow.com/questions/11679568/… "pthreads (7) descreve que o POSIX.1 exige que todos os threads em um processo compartilhem atributos, incluindo disposições de sinal"
steve
@ steve Obrigado, mas 1) está em outro site SE 2) essa especificação não especifica claramente, o que exatamente acontecerá. O que isso significa, os manipuladores de sinal serão chamados em todos os threads, mas me parece um pouco surrealista. 3) Essa resposta não especifica qual era o modelo de Linus e por que / como é usado atualmente.
peterh - Restabelece Monica

Respostas:

9

A entrada no POSIX em " Geração e entrega de sinal " em "Justificativa: Informações gerais sobre interfaces do sistema" diz

Os sinais gerados para um processo são entregues para apenas um encadeamento. Assim, se mais de um segmento é elegível para receber um sinal, um deve ser escolhido. A escolha dos encadeamentos fica inteiramente a cargo da implementação, tanto para permitir a maior variedade possível de implementações em conformidade quanto para dar às implementações a liberdade de transmitir o sinal ao encadeamento "mais fácil possível", caso haja diferenças na facilidade de entrega entre encadeamentos diferentes.

No signal(7)manual em um sistema Linux:

Um sinal pode ser gerado (e, portanto, pendente) para um processo como um todo (por exemplo, quando enviado usando kill(2)) ou para um encadeamento específico (por exemplo, certos sinais, como SIGSEGV e SIGFPE, gerados como consequência da execução de uma máquina específica) As instruções de idioma são direcionadas por thread, assim como os sinais direcionados a um thread específico usando pthread_kill(3)). Um sinal direcionado ao processo pode ser entregue a qualquer um dos encadeamentos que atualmente não tem o sinal bloqueado. Se mais de um dos threads tiver o sinal desbloqueado, o kernel escolherá um thread arbitrário para o qual o sinal será entregue.

E em pthreads(7):

Threads têm configurações distintas de pilha de sinais alternativos. No entanto, as configurações de pilha de sinais alternativos de um novo encadeamento são copiadas do encadeamento que o criou, para que os encadeamentos compartilhem inicialmente uma pilha de sinal alternativo (corrigida no kernel 2.6.16).

Do pthreads(3)manual em um sistema OpenBSD (como exemplo de uma abordagem alternativa):

Manipuladores de sinais normalmente são executados na pilha do encadeamento atualmente em execução.

(No momento, não estou ciente de como isso é tratado quando vários threads estão sendo executados simultaneamente em uma máquina com vários processadores)

A implementação mais antiga do LinuxThread dos encadeamentos POSIX apenas permitia que encadeamentos distintos fossem direcionados por sinais. Em pthreads(7)um sistema Linux:

O LinuxThreads não suporta a noção de sinais direcionados ao processo: os sinais podem ser enviados apenas para threads específicos.

Kusalananda
fonte