부모 플레이가 N 개의 하위 프로세스에 대해 4 개를 연결하는 과제를위한 프로그램을 작성 중입니다. 이 프로그램은 파이프를 사용하여 프로세스간에 게임 이동을 알립니다.포크()와 파이프()로 레이스 컨디션
그러나 내 프로그램에있는 경쟁 조건을 수정하는 데 문제가 있습니다. 게임이 끝난 후 자식 프로세스가 read() 호출을 중단시키는 조건이 있습니다. 이것은 하나 이상의 자식 프로세스가있는 경우에만 발생하는 것으로 보입니다.
필자는 명명 된 세마포어와 같은 여러 가지 사항을 시도했지만 포크, 파이프 및 IPC에 대해서는 아직 완전히 익숙하지 않습니다. 내가 관련 코드와 요지를 게시 한 여기에 (나는 최선 내가 가독성을 위해 할 수있는 한 그것을 청소하려고) :
어떤 도움을 크게
편집을 감상 할 수있다
다음은 선언이 추가 된 요지의 관련 소스입니다.
int main (int argc, char const *argv[])
{
int dimension = 8, children = 2, i;
int child_play_to_win = 0;
int fd[children][4];
pid_t childpid[children];
Board** boards = (Board**) malloc(sizeof(Board*) * children);
GameMove* lastMove, *tmpMove;
char buf[80];
for(i = 0; i < children; i++) {
generate_board(&(boards[i]), dimension);
int tmp[2];
pipe(tmp);
// child read
fd[i][0] = dup(tmp[0]);
// parent write
fd[i][1] = dup(tmp[1]);
pipe(tmp);
// parent read
fd[i][2] = dup(tmp[0]);
// child write
fd[i][3] = dup(tmp[1]);
childpid[i] = fork();
if(childpid[i] == -1) {
perror("fork");
exit(1);
}
if(childpid[i] == 0) {
srand(getpid());
close(fd[i][1]);
close(fd[i][2]);
while(!boards[i]->finished) {
// Read in move from parent
printf("child[%d] about to read\n", getpid());
read(fd[i][0], &buf, sizeof(GameMove));
// repeat parent move on this board
if(gameNotFinished) {
// make child move
// write move back to parent
write(fd[i][3], lastMove, sizeof(GameMove));
// If the board is finished (there was a win),
if (!gameNotFinihsed) {
// Child wins
close(fd[i][0]);
close(fd[i][3]);
printf("child[%d] ending\n", getpid());
break;
}
}
else {
// Parent won
close(fd[i][0]);
close(fd[i][3]);
break;
}
}
dealloc(boards[i]);
exit(0);
}
}
// When this hits children amount, all games are done
int games_complete = 0;
// Make first move to all children
for (i = 0; i < children; i++) {
close(fd[i][0]);
close(fd[i][3]);
lastMove = placePieceAtBestPosition(boards[i], 1);
printf("parent writing to child[%d]\n", childpid[i]);
write(fd[i][1], lastMove, sizeof(GameMove));
}
while (games_complete != children) {
for (i = 0; i < children; i++) {
// Read move from child
read(fd[i][2], &buf, sizeof(GameMove));
// repeat child move
// Check for a child win...
if (!checkForWin(boards[i], 2)) {
// No win yet, place piece at best position
lastMove = placePieceAtBestPosition(boards[i], 1);
// check for win again
boards[i]->finished = checkForWin(boards[i], 1);
// Write move back to child
write(fd[i][1], lastMove, sizeof(GameMove));
// If we won, close everything up and increment
// the games_complete counter.
if(boards[i]->finished) {
close(fd[i][1]);
close(fd[i][2]);
games_complete++;
}
} else {
// write back child move if there was a win
write(fd[i][1], lastMove, sizeof(GameMove));
close(fd[i][1]);
close(fd[i][2]);
printf("Parent lost!):\n");
games_complete++;
}
}
}
게시하시기 바랍니다 (의 관련 부분) 귀하의 질문에 직접 코드가 아닌 링크를 통해. 감사. –
나에게 맞는 첫 번째 일은 파이프를 만든 후에 이러한'dup' 호출이 필요 없다는 것입니다. 특히 원본 파일 설명자를 닫지 않으므로 특히 그렇습니다. 작성하는 하위 프로세스의 수에 따라 파일 설명자 테이블을 채울 수 있습니다. –
* 왜 * 100 개 이상의 코드 행을 연결하고 소스 파일의 맨 위에 시작 함수 선언을 포함시키지 않습니까? – WhozCraig