Gå til innhold

Anbefalte innlegg

Hei,

Jeg driver å lager et program som kan starte x andre program. programmet er egentlig et spill med et sett regler (sjakk, etc)

./game -ai testai1 -ai testai2

der testai1 og testai2 er to program.

 

Kommunikasjonen er tenkt skjedd gjennom pipes. Dvs at når game starter testai1 og testai2 så setter den stdin og stdout til pipen. Dette gjør den ved å forke seg selv og la childprosessen execute testai'ne.

 

En del hardkodede verdier og magi i kodesnuttene jeg paster, men dette kommer jeg til å fikse når jeg bare får dette til å funke...

GameProcess* CoreGameController::StartProcess(const char* program)
{
       pid_t pid;
       GameProcess* process = new GameProcess();
       /* Setup communication pipeline first */
       if(pipe(process->pipe)){
               fprintf(stderr, "Pipe failed!\n");
               exit(1);
       }

       /* Attempt to fork and check for errors */
       if( (pid=fork()) == -1){
               fprintf(stderr, "Fork error. Exiting.\n");
               exit(1);
       }
       if(pid)
       {
               return process;
       }
       // child program should execute program
       else
       {
               dup2(process->pipe[0],0);       /* Replace stdin with the in side of the pipe */
               dup2(process->pipe[1],1);       /* Replace stdout with the out side of the pipe */

               /* Replace the child fork with a new process */
               if(execl(program, program,NULL) == -1){
                       fprintf(stdout, "bye\n");
                       fprintf(stderr, "execl Error!\n");
                       exit(1);
               }
               exit(0);
       }

}

 

Spørsmålene mine er:

- Game er tenkt slik at det kan gå med x antall ai'er. om det mangle ai vil den be om input i fra stdin. Tanken min var i utganspunktet å la game bytte stdin fra pipe til "vanlig" stdin. (for å få protkollen "seamless"). Men her møter jeg på litt problemer (kanskje det bare er en veldig dårlig idè?)

 

Fra main testloopen min

Definisjonen er:

GameOfTheGeneralsController : public CoreGameController

 

int GameOfTheGeneralsController::Run()
{
       for (int i = 0; i < 5; i++)
       {
               for (GameProcessMap_t::iterator iProcess = participants.begin(); iProcess != participants.end(); ++iProcess)
               {
                       int input;
                       GameProcess* process = iProcess->second;

                       FILE* outfd = stdout;
                       FILE* infd = stdin;
                       if (process != NULL)
                       {
                               outfd = fdopen(process->pipe[1], "w");
                               infd = fdopen(process->pipe[0], "r");
                       }
                       fprintf(outfd, "Turn: %d\nInput Something: ", i);
                       char buff[512];
                       fgets(buff, 512, infd);
                       fprintf(stdout, "Got %s from process ", buff);
                       if (process != NULL)
                       {
                               fclose(outfd);
                               fclose(infd);
                       }
               }
       }
       return 1;
}

 

til testai

#include <iostream>
int main()
{
  char dummy[512];
       std::cout << "im just a dumb program" << std::endl;
       std::cin >> dummy;
       std::cout << "that do what i am told" << std::endl;
       std::cin >> dummy;
       std::cout << "printing out text" << std::endl;
       std::cin >> dummy;
       std::cout << "oh i am bold" << std::endl;
       std::cin >> dummy;
       std::cout << "the end" << std::endl;
       return 666;
}

 

 

Problemet mitt når jeg kjører dette er at det krasjer etter 1 runde (fopen feiler).

 

Så det jeg egentlig lurer på er om det er en god idè å åpne og lukke pipene med file descriptors slik jeg gjør. Eller burde jeg bare behandlet io med write() og read() istede? (da vil jeg få 1 case for spillere og 1 case for ai, jeg vil helst ha samme api'et)

 

Jeg er skikkelig noob på pipes så om jeg gjør åpenbare feil, vennligst si i fra!

 

Har noen noen andre ide'er rundt hvordan jeg kan gjøre dette?

Endret av [kami]
Lenke til kommentar
Videoannonse
Annonse

Hvorfor blander du C og C++ API-er på denne måten?

 

fordi jeg i utgangspunktet ville bruke iostreams.. men så funka ikke det så bra med pipes (dup2, etc).

Så quick and dirty'a jeg det over til printf syntaks..

 

Clientene kan greit kjøre iostreams da de ikke trenger å manipulere sin egen stdin stdout (da dette allerede blir satt av parent prosessen) (og dette er separate program)

Endret av [kami]
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...