Я пытаюсь использовать pipe()
от родителя к детям, чтобы суммировать части файла. Дети получают позицию в файле, суммируют свои обозначенные номера, отправляют свою сумму обратно, а родитель суммирует дочерние суммы.Select() никогда не возвращает true
У меня возникли проблемы с кодом в родительском разделе, чтобы прочитать его, когда это будет сделано.
Код:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/select.h>
#include <time.h>
int main(int argc, char *argv[])
{
int numchild;
struct timeval stop, start;
int i, j, len, ret, fpos=0, val, count=0, total=0, alltotal=0;
pid_t pid;
int nums = 1000;
FILE * file;
printf("How many children to use: ");
scanf("%d", &numchild);
printf("\nWill use %d child process(es).\n", numchild);
gettimeofday(&start, NULL);
int fd[numchild][2]; //parent to child. one for each
int results[2]; //all children to parent
pipe(results);
fd_set result_fd;
FD_ZERO(&result_fd);
FD_SET(results[0], &result_fd);
struct timeval tm = {.tv_sec=0, .tv_usec=1};
// create all pipes
for (i=0; i<numchild; i++)
{
pipe(fd[i]);
}
for (i=0; i<numchild; i++)
{
if((pid = fork()) == 0) // child process
{
pid = getpid();
// read from parent
len = read(fd[i][0], &fpos, sizeof(fpos));
if (len > 0)
{
file = fopen("file1.dat", "r");
fseek (file, fpos, SEEK_SET);
count = 0;
total = 0;
printf("Child(%d): Recieved position: %d\n", pid, fpos);
// read from file starting at fpos
// add values read to a total value
while (count < (nums/numchild))
{
fscanf(file, "%i", &val);
total += val;
count++;
}
//write to parent
write(results[1], &total, sizeof(total));
printf("Child(%d): Sent %d to parent.\n", pid, total);
}
else
{
printf("Child(%d): Error with len\n", pid);
}
_exit(0);
}
// parent process
pid = getpid();
fpos = ((i*nums*5)/numchild); // 5 is the offset of the file values
// write to child process
printf("Parent(%d): Sending file position to child\n", pid);
write(fd[i][1], &fpos, sizeof(fpos));
// wait for child responce
ret = select(2, &result_fd, NULL, NULL, &tm);
printf("\t\t%d\n", (FD_ISSET(results[0], &result_fd)));
if (FD_ISSET(results[0], &result_fd))
{
ret = read(results[0], &total, sizeof(total));
// output total
printf("Parent(%d): Recieved %d from child.\n", pid, total);
alltotal += total;
}
}
wait(0);
gettimeofday(&stop, NULL);
printf("\tTime elapsed: %lu microseconds\n", stop.tv_usec - start.tv_usec);
}
В нижней части, мой if (FD_ISSET(results[0], &result_fd))
никогда не возвращает ничего, кроме 0, я верю. Мне нужно его активировать, чтобы мой родитель суммировал дочерние суммы.
Вы видите, что не так?
Попробуйте передать значение, большее, чем любое fd в вашем наборе (или просто 'FD_SETSIZE', как первый аргумент' select', а не номер 2. –
@R .. это ничего не делает для меня. Родитель по-прежнему не выводит никаких итогов. – Tawm
'tm = {.tv_sec = 0, .tv_usec = 1}'. Вы устанавливаете тайм-аут 'select' в 1 * микросекунду *. Так что, вероятно, это не так. – kaylum