编写一个使用两个进程(而不是线程)对C进行排序的C程序 目录中的常规文件和基于文件的子目录 大小。该程序产生一个进程(即子进程)进行扫描 常规文件的目录和子目录。当。。。的时候 (子)进程找到一个常规文件,它获取大小,然后发送 通过的父进程的文件大小和路径名 管道或FIFO。父进程排序(按升序排列)和 组织大小和路径名信息。当孩子进程 完成扫描,它通知父进程和父进程 process打印出文件的大小和路径名。
#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
答案 0 :(得分:1)
sizeof dirPath
返回指针的大小,而不是长度
串。由于read
和write
没有消息边界,因为Mark Plotnick指出了这一点
在注释中,您需要声明字符串的修复大小
(意思是父母和孩子使用相同的大小)或孩子写的长度
字符串然后是字符串。我会选择第二个:
对于孩子:
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);
是一个坏主意,您正在发送指针的地址。这个地址最多 可能只在孩子的虚拟空间的记忆中有效,你没有 保证父进程在同一地址具有相同的信息 在父虚拟空间中,父节点可能会尝试访问它的内存 不被允许。您必须发送数组的内容或者如果您愿意 避免这种情况,那么你必须使用共享内存。
最后一件事,你不是wait
让孩子结束。你应该这样做:
close(pipes[i][1]);
int childProcessStatus;
waitpid(processCheck[0], &childProcessStatus, 0);
if(WIFEXITED(childProcessStatus)&&WEXITSTATUS(childProcessStatus)==0)
{
...
}