Como lidar com fork () corretamente com boost :: asio em um programa multithread?

Estou tendo problemas para entender como lidar corretamente com a criação de um processo filho a partir de um programa multithread que usa o Boost Asio de uma maneira multithread.

Se bem entendi, a maneira de iniciar um processo filho no mundo Unix é chamarfork() seguido por umexec*(). Além disso, se eu entendi direito, chamandofork() duplicará todos os descritores de arquivos e assim por diante, e estes precisam ser fechadosno processo filho a menos que marcado comoFD_CLOEXEC (e, portanto, sendo atomicamente fechado ao chamarexec*())

O Boost Asio precisa ser notificado quandofork() é chamado para operar corretamente chamandonotify_fork(). No entanto, em um programa multithread, isso cria vários problemas:

Por padrão, os soquetes são herdados por processos filho, se bem entendi. Eles podem ser configurados paraSOCK_CLOEXEC - mas não diretamente na criação*, levando a uma janela de tempo se um processo filho estiver sendo criado a partir de outro encadeamento.

notify_fork() requer que nenhuma outra chamada de threadqualquer outroio_service funçãonemqualquer função em qualquer outro objeto de E / S associado aoio_service. Isso realmente não parece viável - afinal, o programa é multithread por um motivo.

Se bem entendi, qualquer chamada de função feita entrefork() eexec*() precisa ser seguro para sinal assíncrono (consultefork() documentação) Não há documentação donotify_fork() chamada sendo sinal assíncrono seguro. De fato, se eu olhar o código fonte do Boost Asio (pelo menos na versão 1.54), pode haver chamadas parapthread_mutex_lock, qual énão sinal assíncrono seguro se eu entendi corretamente (consulteConceitos de Sinal, há também outras chamadas que não estão na lista branca).

Problema nº 1 Provavelmente, posso resolver a questão separando a criação de processos filho e sockets + arquivos, para garantir que nenhum processo filho seja criado na janela entre um soquete sendo criado e a configuraçãoSOCK_CLOEXEC. A edição nº 2 é mais complicada, eu provavelmente precisaria me certificar de quetudo os threads do manipulador asio estão parados, faça a bifurcação e depois os recrie novamente, o que é maré na melhor das hipóteses e realmente muito ruim na pior (e meus temporizadores pendentes ??). O problema nº 3 parece impossibilitar o uso correto.

Como uso corretamente o Boost Asio em um programa multithread junto comfork() + exec*()? ... ou estou "bifurcada"?

Por favor, deixe-me saber se eu entendi mal algum conceito fundamental (sou educado em programação para Windows, não * nix ...).

Edit: * - Na verdade é possível criar soquetes comSOCK_CLOEXEC configurado diretamente no Linux, disponível desde 2.6.27 (consultesocket() documentação) No Windows, o sinalizador correspondenteWSA_FLAG_NO_HANDLE_INHERIT está disponível desde o Windows 7 SP 1 / Windows Server 2008 R2 SP 1 (consulteWSASocket() documentação) O OS X parece não suportar isso.

questionAnswers(2)

yourAnswerToTheQuestion