gpt4 book ai didi

c - fork 和管道之间的 2 种方式通信

转载 作者:太空宇宙 更新时间:2023-11-04 03:53:26 25 4
gpt4 key购买 nike

我正在尝试在主文件和辅助文件之间进行双向通信。主文件 fork ,子文件做一些管道工作,然后运行一个 exec。我的问题是我可以将信息从子 exec 发送到父 exec,但反之则不行。下面是我来自这两个文件的全部代码,因此您应该能够运行它。使双向通信正常工作的任何帮助都将非常有帮助。我现在已经连续工作了将近 8 个小时。

当你运行它时,你会看到它打印出“yo 0”。这是我测试它从主文件中获取一个整数,将其发送给帮助程序,在它前面添加 yo 并将其发回。第一个代码块是主文件,第二个是帮助程序,第三个是运行它所需的映射文件。确保最后一行下面没有空行,第四行是运行它所需的代理文件。

正在运行的是[./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);


}

map 文件

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

代理文件

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

最佳答案

管道是跨进程的单向连接。在你 fork 之前,你打开管道,它会保留两个文件描述符,其中 fd[0] 可以读取,fd[1] 可以写入。

因此,当您想要进行双向通信时,您需要创建两个管道,然后使用一个管道在父级中读取并在子级中写入,而第二个管道则相反。

可以在此处找到更详细的解释以及一些示例代码:http://linux.die.net/man/2/pipe

关于c - fork 和管道之间的 2 种方式通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19021708/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com