2013-09-26 2 views
1

주 파일과 도우미 파일 사이에 양방향 통신을 시도하고 있습니다. 주 파일이 분기되고 자식이 파이프 작업을 수행 한 다음 exec를 실행합니다. 내 문제는 내가 자식 간부로부터 부모 간부에게 정보를 보낼 수 있지만 그 반대가 아닙니다. 아래 두 파일의 전체 코드가 있으므로 실행할 수 있어야합니다. 양방향 의사 소통 작업에 도움이 될 것입니다. 나는 지금 거의 8 시간 동안 똑바로있다.포크와 파이프 사이의 양방향 통신

실행하면 "yo 0"이 출력됩니다. 이것은 필자가 주 파일에서 정수를 취하여 도우미에게 보내고, 앞에 요를 더하여 되돌려 보내는 테스트입니다. 코드의 첫 번째 슬랩은 주 파일이고 두 번째는 도우미이며 세 번째는 실행에 필요한 맵 파일입니다. 마지막 행 아래에 빈 줄이 없는지 확인하고 네 번째 줄은 실행하기 위해 필요한 에이전트 파일입니다.

실행중인 [./handler mapfile 20 agentfile.] int 20은 아직 아무 것도하지 않지만 파일을 실행하려면 거기에 필요합니다. 사람이 실제로 나에게이 모든 작업을 수행하고 도움이되는 노력에 가면 , 나는 영원히 감사

기본 파일 (handler.c)

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <unistd.h> 
#include <sys/wait.h> 


enum ErrorCode { 
     SHOW_USAGE = 1, BAD_STEPS, OPEN_MAP_ERROR, CORRUPT_MAP, 
     OPEN_AGENT_ERROR, CORRUPT_AGENTS, AGENT_ERROR, 
     AGENT_WALLED, AGENT_COLLIDED, TOO_MANY_STEPS, INVALID_AGENT_RESPONSE, 
     AGENT_CLOSED, AGENT_DIED, SIGINT_REC 
}; 

typedef struct { 
     int valid; 
     int row, col; 
} Point; 

typedef struct { 
     Point point; 
     int number; 
     char name; 
     char param[20]; 
     char type[20]; 
} Agent; 

typedef struct { 
     int rows, cols; 
     char **grid; 
} Map; 

Map map; 
Map agentMap; 
int listSize = 0; 

void error(enum ErrorCode e) { 
     switch(e) { 
     case SHOW_USAGE: 
       fprintf(stderr, "Usage: handler mapfile maxsteps agentfile\n"); 
       break; 
     case BAD_STEPS: 
       fprintf(stderr, "Invalid maxsteps.\n"); 
       break; 
     case OPEN_MAP_ERROR: 
       fprintf(stderr, "Unable to open map file.\n"); 
       break; 
     case CORRUPT_MAP: 
       fprintf(stderr, "Corrupt map.\n"); 
       break; 
     case OPEN_AGENT_ERROR: 
       fprintf(stderr, "Unable to open agent file.\n"); 
       break; 
     case CORRUPT_AGENTS: 
       fprintf(stderr, "Corrupt agents.\n"); 
       break; 
     case AGENT_ERROR: 
       fprintf(stderr, "Error running agent.\n"); 
       break; 
     case AGENT_WALLED: 
       fprintf(stderr, "Agent walled.\n"); // needs fixing, check spec sheet 
       break; 
     case AGENT_COLLIDED: 
       fprintf(stderr, "Agent collided.\n"); // same as AGENT_WALLED 
       break; 
     case TOO_MANY_STEPS: 
       fprintf(stderr, "Too many steps.\n"); 
       break; 
     case INVALID_AGENT_RESPONSE: 
       fprintf(stderr, "Agent sent invalid response.\n"); // fixiing 
       break; 
     case AGENT_CLOSED: 
       fprintf(stderr, "Agent exited with status.\n"); // fixiing 
       break; 
     case AGENT_DIED: 
       fprintf(stderr, "Agent exited due to signal.\n"); // fixing 
       break; 
     case SIGINT_REC: 
       fprintf(stderr, "Exiting due to INT signal.\n"); 
       break; 
     } 
     exit(e); 
} 


void print_map(Map map) 
{ 
     int r; 
     for (r = 0; r < map.rows; ++r) { 
       printf("%s", map.grid[r]); 
     } 
     puts(""); 
} 

void print_agents(Agent *agents, int size) 
{ 
     int i; 
     for (i = 0; i < size; i++) { 
       Agent temp = agents[i]; 
       printf("%d %d %c %d %s %s %i\n", temp.point.row, temp.point.col, temp.name, temp.number, temp.type, temp.param, i); 
     } 
     puts(""); 
} 


void readMap(char *file) 
{ 
     int r; 
     FILE *fd = fopen(file, "r"); 
     char buffer[20]; 
     char d; 

     if (!fd) { 
       error(OPEN_MAP_ERROR); 
     } 

     if (fgets(buffer, 20, fd) == NULL) { 
       error(CORRUPT_MAP); 
     } 

     if (sscanf(buffer, "%d %d%1[^\n]\n", &map.rows, &map.cols, &d) != 2 || 
      map.rows < 1 || map.rows > 999 || map.cols < 1 || map.cols > 999) { 
       error(CORRUPT_MAP); 
     } 

     map.grid = malloc(map.rows * sizeof(char *)); 
     for (r = 0; r < map.rows; ++r) { 
       map.grid[r] = calloc(map.cols + 2, sizeof(char)); 
       if (fgets(map.grid[r], map.cols + 2, fd) == NULL || 
             map.grid[r][map.cols] != '\n') { 
         error(CORRUPT_MAP); 
       } 
     } 

     fclose(fd); 

} 

void checkAgent(char *file) 
{ 
     FILE *fd = fopen(file, "r"); 
     if (!fd) { 
       error(AGENT_ERROR); 
     } 
     fclose(fd); 
} 

int growList (Agent **agentList, int curSize, int increaseNum) 
{ 
     const int newSize = curSize + increaseNum; 
     Agent *temp = (Agent*) realloc(*agentList, (newSize * sizeof(Agent))); 

     if (temp == NULL) { 
       exit(20); 
     } 
     else { 
       *agentList = temp; 
       return newSize; 
     } 
} 


Agent* readAgentFile(char *file, Agent *agentList) 
{ 
     int readCount = 0; 
     FILE *fp = fopen(file, "r"); 
     char buffer[80]; 

     listSize = 0; 
     if (!fp) { 
       error(OPEN_AGENT_ERROR); 
     } 

     if (fgets(buffer, 80, fp) == NULL) { 
       error(CORRUPT_AGENTS); 
     } 

     rewind(fp); 
     while (fgets(buffer, 80, fp) != NULL) { 
       if (buffer[0] != '#') { 
         Agent agent; 
         sscanf(buffer, "%d %d %c %s %s" ,&agent.point.row, &agent.point.col, &agent.name, agent.type, agent.param); 
         checkAgent(agent.type); 
         agent.number = readCount+1; 
         listSize = growList(&agentList, listSize, 1); 
         agentList[readCount] = agent; 
         readCount++; 
       } 
     } 
     if (readCount == 0) { 
       error(CORRUPT_AGENTS); 
     } 

     fclose(fp); 
     return agentList; 
} 

void createAgentMap() 
{ 
     int i,j; 
     agentMap = map; 
     for (i=0; i < map.rows; i++) { 
       for (j=0; j < map.cols; j++) { 
         char c = map.grid[i][j]; 
         if (c == '.') { 
           agentMap.grid[i][j] = ' '; 
         } 
       } 
     } 
} 

int main(int argc, char **argv) 
{ 
     int steps; 
     int pid; 
     int returnStatus; 
     int i; 
     int out_pipe[2]; 
     int in_pipe[2]; 
     char ch[20]; 

     Agent firstAgent; 
     Agent *agentList =(Agent *) calloc(1, sizeof(Agent)); 

     if (argc != 4) { 
       error(SHOW_USAGE); 
     } 

     sscanf(argv[2], "%d", &steps); 
     if ((steps < 1)) { 
       error(BAD_STEPS); 
     } 

     readMap(argv[1]); 
     agentList = readAgentFile(argv[3], agentList); 
     firstAgent = agentList[0]; 
     createAgentMap(); 

     for (i=0; i < listSize; i++) { 

       if (pipe(out_pipe) < 0) { 
         perror("Pipe Error"); 
       } 
       if (pipe(in_pipe) < 0) { 
         perror("Child pipe error"); 
       } 

       Agent temp; 
       temp = agentList[i]; 

       switch (pid = fork()) 
       { 
         case -1: 
           perror("Can't fork.\n"); 
           exit(20); 
         case 0: 
           /* Child */ 
           /*close(1); 
           dup(in_pipe[1]); 
           close(0); 
           dup(out_pipe[0]); 
           close(in_pipe[0]); 
           close(out_pipe[1]);*/ 

           dup2(out_pipe[0], 0); 
           dup2(in_pipe[1], 1); 

           execlp(temp.type, temp.type, temp.param, (char *)0); 
           perror("No exec"); 
         default: 
           //close(1); 
           //dup(handlerChild[1]); 
           //fprintf(stdout, "%d", listSize); 

           write(out_pipe[1], "%d", listSize); 

           close(in_pipe[1]); 
           close(0); 
           dup(in_pipe[0]); 

           if (fgets(ch, 20, stdin) == NULL) { 
             break; 
           } 
           printf("%s\n", ch); 
       } 

     } 

     while (steps > 0) { 


       steps -= 1; 

     } 

     return 0; 

} 

도우미 파일 (simple.c)

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

typedef struct { 
     int valid; 
     int row, col; 
} Point; 

typedef struct { 
     int numAgents; 
     char agentNames[80]; 
     int agentNumber; 
} Info; 

typedef struct { 
     int rows, cols; 
     char **grid; 
} Map; 

Map agent_map; 

int main(int argc, char **argv) 
{ 
     int steps = 10; 
     int simple_pipe[2]; 
     int dir; 
     char inputDir; 
     char input_stream[20]; 
     int in = dup(0); 
     Info info; 

     if (argc == 2) { 
       sscanf(argv[1], "%c1", &inputDir); 
       switch (inputDir) { 
         case 'N': dir = 0; break; 
         case 'E': dir = 1; break; 
         case 'S': dir = 2; break; 
         case 'W': dir = 3; break; 
         default : fprintf(stdout, "Invalid params.\n"); exit(2); 
       } 

     } 
     else { 
       fprintf(stdout, "Incorrect number of params.\n"); 
       exit(1); 
     } 

     close(0); 
     dup(simple_pipe[0]); 
     fgets(input_stream, 20, stdin); 

     sscanf(input_stream, "%d", &info.numAgents); 
     //printf("%d", info.numAgents); 
     //printf("this is the input: %s\n", input_stream);  // This is successfully printing to stdout in the pipe 
     fprintf(stderr, "yo %d \n", info.numAgents); 
     while (steps > 0) { 


     steps -= 1; 
     } 
     exit(0); 


} 

맵 파일

6 6 
##..## 
#....# 
#.##.# 
#....# 
##.... 
###### 

에이전트 파일

1 1 A ./simple E 
2 2 B ./simple N 
5 2 C ./simple S 

답변

1

파이프는 프로세스간에 일방적 인 연결입니다. 포크하기 전에 파이프를 열면 fd [0]을 읽을 수 있고 fd [1]을 쓸 수있는 두 개의 파일 설명자가 예약됩니다.

양방향 해석을하려면 두 개의 파이프를 만들고 그 중 하나를 사용하여 자식의 부모 글을 읽고 다른 파이프를 다른 방법으로 읽어야합니다. 나는 이미 내가 바로 그것을하고있어 경우에 단지 확실하지 않다 무엇 파이프입니다 무슨 뜻인지 이해 생각 http://linux.die.net/man/2/pipe

+0

: 일부 샘플 코드와 함께

더 자세한 설명은 foun dhere 될 수 있습니다 2 exec 함수 사이의 할당 –

+0

dup()을 호출하고 있지만 어디에도 새 fd를 할당하지 않았습니다. – Devolus