[kami] Skrevet 8. november 2010 Del Skrevet 8. november 2010 (endret) 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 8. november 2010 av [kami] Lenke til kommentar
GeirGrusom Skrevet 8. november 2010 Del Skrevet 8. november 2010 Hvorfor blander du C og C++ API-er på denne måten? Lenke til kommentar
[kami] Skrevet 8. november 2010 Forfatter Del Skrevet 8. november 2010 (endret) 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 8. november 2010 av [kami] Lenke til kommentar
Anbefalte innlegg
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 kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå