Introdução
Se você deseja enviar um sinal para um thread
, você pode usar pthread_kill()
, embora não seja semanticamente correto, a página man7 afirma:
A função pthread_kill() envia o sinal
sig
parathread
, um thread no mesmo processo que o chamador. O sinal é direcionado de forma assíncrona ao thread.Se
sig
for 0, nenhum sinal será enviado, mas a verificação de erros ainda será realizada.
Vivo ou Morto?
Thread
Um código para obter o sinal de uma thread
e verificar se a thread
está “viva”:
pthread_t m_iThreadID = your_thread_id_here;
int iStatus = pthread_kill( m_iThreadID, 0 );
if( iStatus != 0 )
{
// Thread Stopped!
std::cout << "pthread_kill Error: " << errno << std::endl;
}
Porém, é semanticamente estranho usar uma função kill para recuperar um sinal e não matar o thread, certo?
Embora pareça estranho, pthread_kill() é amplamente utilizado e possui muitos tutoriais e exemplos.
Se você quiser usar outra função ou enviar parâmetros, pthread_sigqueue() pode ser usado. Da página de manual:
A função
pthread_sigqueue()
executa uma tarefa semelhante a sigqueue(3), mas, em vez de enviar um sinal para um processo, ele envia um sinal para um thread no mesmo processo que o thread chamador.O argumento thread é o ID de um thread no mesmo processo que o chamador. O argumento sig especifica o sinal a ser enviado. O argumento value especifica dados para acompanhar o sinal; ver sigqueue(3) para detalhes.
O argumento opcional na página de manual:
O argumento value é usado para especificar um item acompanhante de dados (um número inteiro ou um valor de ponteiro) a serem enviados com o sinal, e tem o seguinte tipo:
union sigval { int sival_int; void *sival_ptr; };
Um exemplo com um argumento value nulo:
pthread_t m_iThreadID = your_thread_id_here;
sigval_t siValue;
int iStatus = pthread_sigqueue( m_iThreadID, 0, siValue );
if( iStatus != 0 )
{
// Thread Stopped!
std::cout << "pthread_sigqueue Error: " << errno << std::endl;
}
Processos
O mesmo pode ser aplicado aos processos!
A função kill() pode ser usada para obter o status de uma função, na página man:
A chamada de sistema kill() pode ser usada para enviar qualquer sinal para qualquer grupo de processos ou processo.
Se pid for positivo, então o sinal sig é enviado ao processo com o ID especificado pelo
pid
.Se
pid
for igual a 0, então sig é enviado para todos os processos do processo grupo do processo de chamada.Se
pid
for igual a -1, então sig é enviado para todos os processos para os quais o o processo de chamada tem permissão para enviar sinais, exceto para processo 1 (init), mas veja abaixo.Se
pid
for menor que -1, então sig é enviado para todos os processos no grupo de processos cujo ID é -pid.Se
sig
for 0, nenhum sinal será enviado, mas as verificações de existência e permissão ainda são realizadas; isso pode ser usado para verificar a existência de um ID de processo ou ID de grupo de processos que o chamador está permitido sinalizar.Para que um processo tenha permissão para enviar um sinal, ele deve ser privilegiado (no Linux: ter o recurso CAP_KILL no namespace do usuário do processo alvo), ou o real ou efetivo ID do usuário do processo de envio deve ser igual à configuração real ou salva. No caso do SIGCONT, é suficiente quando os processos de envio e recebimento pertencem ao mesma sessão. (Historicamente, as regras eram diferentes; veja NOTAS.)
Um exemplo:
pid_t m_iProcID = your_proc_id_here;
int iStatus = kill( m_iProcID, 0 );
if( iStatus != 0 )
{
// Process Stopped!
std::cout << "kill Error: " << errno << std::endl;
}
Ou para usar o sigqueue()
:
pid_t m_iProcID = your_proc_id_here;
sigval_t siValue;
int iStatus = sigqueue( m_iProcID, 0, siValue );
if( iStatus != 0 )
{
// Process Stopped!
std::cout << "sigqueue Error: " << errno << std::endl;
}
Sinais
Os sinais descritos no manual do POSIX podem ser usados para enviar sinais para a thread e uma ação será realizada, por exemplo, para matar uma thread ou processo o SIGKILL
pode ser utilizado.
pthread_kill( m_iThreadID, SIGKILL );
O valor de enum dos sinais podem variar para cada processador ou distribuição do Linux, no Ubuntu os signais podem ser vistos no manual signal - lista de sinais disponíveis.