Pergunta

Eu tenho um projeto que eu pensei que ia ser relativamente fácil, mas está a transformar-se mais de uma dor que eu tinha esperado. Em primeiro lugar, a maior parte do código que estou interagindo com é código legado que não tem controle sobre, por isso eu não posso fazer grandes mudanças de paradigma.

Aqui está uma explicação simplificada do que eu preciso fazer: dizer que tenho um grande número de programas simples que ler de stdin e gravar stdout. (Estes eu não posso tocar). Basicamente, entrada para stdin é um comando como "Set temperatura para 100" ou algo parecido. E a saída é um evento "Temperatura foi definido para 100" ou "Temperatura caiu abaixo de valor nominal".

O que eu gostaria de fazer é escrever uma aplicação que pode iniciar um monte desses programas simples, relógio para eventos e comandos em seguida, enviar a eles como necessário. Meu plano inicial era algo como popen, mas eu preciso de um popen bidirecional para obter ambos os tubos de ler e escrever. Eu cortei algo juntos que eu chamo popen2 onde eu passar o comando para executar e dois FILE * que são preenchidas com o fluxo de ler e escrever. Então tudo necessidade I a fazer é escrever um loop simples que lê de cada um dos stdouts de cada um dos processos, faz a lógica que ele precisa e, em seguida, escreve comandos de volta para o processo adequado.

Eis alguns pseudocódigo

FILE *p1read, *p1write;
FILE *p2read, *p2write;
FILE *p3read, *p3write;

//start each command, attach to stdin and stdout
popen2("process1",&p1read,&p1write);
popen2("process2",&p2read,&p2write);
popen2("process3",&p3read,&p3write);

while (1)
{
   //read status from each process
   char status1[1024];
   char status2[1024];
   char status3[1024];
   fread(status1,1024,p1read);
   fread(status2,1024,p2read);
   fread(status3,1024,p3read);

   char command1[1024];
   char command2[1024];
   char command3[1024];
   //do some logic here

   //write command back to each process
   fwrite(command1,p1write);
   fwrite(command2,p2write);
   fwrite(command3,p3write);
}

O programa real é mais complicado onde espreita no fluxo para ver se alguma coisa está esperando, se não, ele irá ignorar esse processo, da mesma forma, se ele não precisa enviar um comando para um determinado processo não faz . Mas este código dá a idéia básica.

Agora, isso funciona muito bem na minha caixa de UNIX e até mesmo muito bom em uma caixa de Windows XP com cygwin. No entanto, agora eu preciso para obtê-lo para trabalhar em Win32 nativamente.

A parte mais difícil é que a minha popen2 usos fork () e execl () para iniciar o processo e atribuir os fluxos para stdin e stdout dos processos filhos. Existe uma maneira limpa eu posso fazer isso no Windows? Basicamente, eu gostaria de criar um popen2 que funciona em janelas do mesmo modo que a minha versão do UNIX. Desta forma, o código específico apenas janelas estaria nessa função e eu poderia sair com tudo funcionando da mesma forma.

Alguma idéia?

Obrigado!

Foi útil?

Solução

No Windows, você invocar CreatePipe primeiro (semelhante ao tubo (2)), em seguida, CreateProcess. O truque aqui é que CreateProcess tem um parâmetro onde você pode passar stdin, stdout, stderr do processo recém-criado.

Observe que quando você usa stdio, você precisa fazer fdopen para criar o objeto de arquivo mais tarde, que espera números de arquivo. No Microsoft CRT, números de arquivos são diferentes dos identificadores de arquivo OS. Então, para voltar a outra extremidade do CreatePipe para o chamador, você primeiro precisa _open_osfhandle para obter um número de arquivo CRT, e em seguida fdopen sobre isso.

Se você quiser ver o código de trabalho, veja _PyPopen em

http://svn.python.org /view/python/trunk/Modules/posixmodule.c?view=markup

Outras dicas

Eu acho que você fez um bom começo para o seu problema usando a função () popen2 abstrair as questões de plataforma cruzada. Eu estava esperando para vir e sugerir 'tomadas', mas eu tenho certeza que isso não é relevante depois de ler a pergunta. Você poderia usar soquetes em vez de tubos -. Ele estaria escondido na função popen2 ()

Estou 99% certo que você pode implementar a funcionalidade necessária no Windows, usando APIs do Windows. O que não pode fazer é apontar-lhe as funções corretas de forma confiável. No entanto, você deve estar ciente da Microsoft tem a maior parte do POSIX-like chamadas de API disponíveis, mas o nome é prefixado com '_'. Há também chamadas de API nativas que atingem os efeitos da fork e exec.

Seus comentários sugerem que você está ciente dos problemas com disponibilidade de dados e possíveis impasses - ser cauteloso

.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top