gpt4 book ai didi

c - ftw 和流程问题

转载 作者:行者123 更新时间:2023-11-30 20:58:54 25 4
gpt4 key购买 nike

Write a C program that uses two processes (not threads) to sort the regular files in a directory and the sub-directories based on file sizes. The program spawns one process (i.e., child process) to scan the directory and the sub-directories for regular files. When the (child) process finds a regular file, it obtains the size, and sends the size and the pathname of the file to the parent process through a pipe or FIFO. The parent process sorts (in ascending order) and organizes the size and pathname information. When the child process finishes scanning, it notifies the parent process, and the parent process prints out the sizes and pathnames of the files.

#define _XOPEN_SOURCE 500
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/wait.h>

static int dirSize = 0;
char *dirPath = NULL;
static int dirInfo(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf){
dirSize = sb -> st_size;
dirPath = fpath;
return 0;
}

int main(int argc, char *argv[]){
pid_t processCheck[1];
int i = 0;
int pipes[1][2];
char *directoryPath = argv[1];
pipe(pipes[i]);
processCheck[0] = fork();
if(processCheck[0]==0){
close(pipes[i][0]);
nftw(directoryPath, dirInfo, 10, FTW_PHYS);
write(pipes[i][1], &dirSize, sizeof dirSize);
write(pipes[i][1], &dirPath, sizeof dirPath);
close(pipes[i][1]);
exit(0);
}
close(pipes[i][1]);
int childProcessStatus;
if(WIFEXITED(childProcessStatus)&&WEXITSTATUS(childProcessStatus)==0){
int v;
char * d=NULL;
if(read(pipes[i][0], &v, sizeof v) == sizeof(v)){
printf("%d\t" , v);
}
if(read(pipes[i][0], &d, sizeof d) == sizeof(d)){
printf("%s\n", d);
}
}
close(pipes[i][0]);
return 0;
}

程序仅打印 4096 4096

最佳答案

sizeof dirPath 返回指针的大小,而不是路径的长度字符串。因为 readwrite 没有消息边界,如 Mark Plotnick指出在注释中,您需要声明字符串的固定大小(意味着父级和子级使用相同的大小)或者子级写入的长度字符串,然后是字符串。我会选择第二个:

对于 child :

size_t len = strlen(dirPath);

write(pipes[i][1], &dirSize, sizeof dirSize);
write(pipes[i][1], &len, sizeof len);
write(pipes[i][1], dirPath, len); // not &dirPath, otherwise you are sending
// an address, not the string

对于父级:

int v;
size_t len;
char *d=NULL;
if(read(pipes[i][0], &v, sizeof v) != sizeof(v))
{
fprintf(stderr, "Invalid answer from child\n");
exit(1);
}

if(read(pipes[i][0], &len, sizeof len) != sizeof len)
{
fprintf(stderr, "Invalid answer from child\n");
exit(1);
}

// don't have to worry about setting the
// \0-terminating byte
d = calloc(len + 1, 1);

if(d == NULL)
{
fprintf(stderr, "out of memory\n");
exit(1);
}

if(read(pipes[i][0], d, len) != len)
{
fprintf(stderr, "Invalid answer from child\n");
free(d);
exit(1);
}

printf("child sent: dirSize = %d\n", v);
printf("child sent: dirPath = %s\n", d);
free(d);
close(pipes[i][0]);

写这个

write(pipes[i][1], &dirPath, sizeof dirPath);

是一个坏主意,您正在发送指针的地址。这个地址最可能只在 child 的虚拟空间的内存中有效,你没有保证父进程在同一地址有相同的信息在父级的虚拟空间中,父级可能会尝试访问它所在的内存不被允许。您必须发送数组的内容,或者如果您想要避免这种情况,那么你必须使用共享内存。

最后一件事,您不会等待子进程结束。你应该这样做:

close(pipes[i][1]);
int childProcessStatus;
waitpid(processCheck[0], &childProcessStatus, 0);

if(WIFEXITED(childProcessStatus)&&WEXITSTATUS(childProcessStatus)==0)
{
...
}

关于c - ftw 和流程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49184104/

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