gpt4 book ai didi

c - Select() 永远不会返回 true

转载 作者:行者123 更新时间:2023-11-30 17:04:01 25 4
gpt4 key购买 nike

我正在尝试使用从父级到子级的pipe()来对文件的各个部分求和。子级接收文件中的位置,对指定的数字求和,将其总和发回,然后父级对子级求和。

我在父部分中的代码在完成后从子部分读取时遇到问题。

代码:

#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 之外的任何内容。我需要激活它才能让我的 parent 对 child 的总和进行求和。

你看出问题所在了吗?

最佳答案

您缺少大量错误检查,这使得几乎不可能对正在发生的情况得出任何结论。

  1. 您没有检查 fopen 的返回值。
  2. 您正在使用 fseek,它可以搜索文件末尾,并且不会失败。您也没有检查 fseek 是否成功。请参阅此处了解一些详细信息。 fseek on a position beyond EOF does not trigger EOF using feof, how come?
  3. 几乎没有检查系统调用是否有效。

我们不知道你用什么编译了这个。难道是这个……

gcc -Wall -迂腐

它给了我错误。您应该使用断言来检查您的假设,即

fpos = ((i*nums*5)/numchild);

当我用测试文件运行该行时,我认为该行会产生一个非常大的数字,如果我搜索到文件末尾,我会在返回中得到一个 0,这是你的问题吗?

在你认为不应该发生某些事情的地方用断言来填充你的代码,即测试所有不变量,无论它们看起来多么愚蠢。 Assert 和 printf 很简单,但非常有效。

关于c - Select() 永远不会返回 true,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35954058/

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