Imagine que eu tenha um mutex bloqueado. Há um número ilimitado de outros segmentos aguardando para bloquear o mutex. Quando eu destrancar o mutex, um desses tópicos será escolhido para entrar na seção crítica. No entanto, não tenho controle sobre qual deles. E se eu quiser um segmento específico para entrar na seção crítica?
Tenho certeza de que isso não pode ser feito usando o POSIX mutex, no entanto, posso emular o comportamento usando objetos de sincronização diferentes?
Respostas:
4 para resposta № 1Você pode usar um mutex, uma variável de condição e um id de thread para achá-lo.
Antes de desbloquear o mutex, o encadeamento defineID do segmento de destino, transmite a variável de condição e libera o mutex. Os segmentos em espera são ativados, bloqueiam o mutex e verificam se o ID do encadeamento de destino é igual a esse ID de encadeamento. Se não, o fio volta a esperar.
Uma otimização para este método para evitar acordartodos os threads de espera apenas para verificar o id do segmento de destino e, em seguida, voltar a esperar seria usar uma variável de condição separada para cada thread em espera. Dessa forma, o encadeamento de sinalização notificaria a variável de condição do encadeamento de destino específico.
Outra opção é usar sinais enviados para um segmento específico. Vamos dizer que nós usamos SIGRTMIN
para este fim. Primeiro, todos os threads bloqueiam este sinal no início, de forma que o sinal fica pendente e não se perde quando o thread não está esperando por ele. Quando um thread quer bloquear o mutex, primeiro chama sigwait()
que atomicamente desbloqueia SIGRTMIN
e espera por ele ou entrega um já pendente. Uma vez que o thread recebeu o sinal, ele pode prosseguir e bloquear o mutex. O encadeamento de sinalização usa pthread_kill(target_thread_id, SIGRTMIN)
para acordar um segmento específico.