我正在尝试在C中创建目录监视程序。到目前为止,它检测主目录的子目录,但是当我尝试监视子目录的子目录时会出现问题。
char * const son[] = { argv[0], name, NULL };
pid_t pid = fork();
if (pid == 0) {
execvp(son[0], son);
}
此代码应创建一个监视子目录的子进程。例如,name
是一个包含子目录“Desktop / test”的字符串。
我之前尝试打印“name”,它是我想要的子目录,所以问题不在这里。
该程序完美无缺,直到我添加它。一旦我添加它,它进入一个无限循环,尽管以前工作。我还想指出我不使用信号所以问题不是来自他们。
编辑: 更好地添加所有代码,argv [1]是目录,argv [2]我希望程序运行多少分钟,argv [3],这是每次扫描之间的暂停。如果我删除上面的摘录并且我知道它有点令人困惑,但是如果你有任何问题,那就可以了。
int main(int argc, char *argv[]) {
char** direc;
int direct_pos = 0;
direc = (char**) malloc(2 * sizeof(char*));
double actual_time = 0;
double MAXTIME = atof(argv[2]);
MAXTIME = MAXTIME * 60;
double IterationTime = atof(argv[3]);
time_t start = time(0);
char dot2[100];
char dot[100];
sprintf(dot, "%s/.", argv[1]);
sprintf(dot2, "%s/..", argv[1]);
direct_pos++;
direc[direct_pos - 1] = (char*) malloc(strlen(dot) * sizeof(char));
strcpy(direc[direct_pos - 1], dot);
direct_pos++;
direc[direct_pos - 1] = (char*) malloc(strlen(dot2) * sizeof(char));
strcpy(direc[direct_pos - 1], dot2);
if (argc != 4) {
fprintf(stderr, "Usage: %s dir_name\n", argv[0]);
exit(1);
}
while (actual_time < MAXTIME) {
DIR *dirp;
if ((dirp = opendir(argv[1])) == NULL) {
perror(argv[1]);
exit(2);
}
struct stat stat_buf;
struct dirent *direntp;
while ((direntp = readdir(dirp)) != NULL) {
char name[100];
sprintf(name, "%s/%s", argv[1], direntp->d_name);
if (lstat(name, &stat_buf) == -1)
{
perror("lstat ERROR");
exit(3);
}
if (S_ISDIR(stat_buf.st_mode))
{
int x;
for (x = 0; x <= direct_pos; x++) {
if (x == direct_pos) {
char**newarray;
newarray = (char**) malloc((direct_pos + 1)* sizeof(char*));
int l;
for (l = 0; l < direct_pos; l++) {
//printf("\nxxxx%d\n", sizeof(direc[l]));
newarray[l] = (char*) malloc((strlen(direc[l])+1)
* sizeof(char));
strcpy(newarray[l], direc[l]);
}
direc = newarray;
direc[direct_pos] = (char*) malloc(sizeof(name)
* sizeof(char));
direc[direct_pos] = strcpy(direc[direct_pos], name);
direct_pos++;
double seconds_since_start = difftime(time(0), start);
double new_time = (MAXTIME - seconds_since_start) / 60;
char time_array[10];
sprintf(time_array,"%f",new_time);
char * const son[] = { argv[0], name, time_array,
argv[3], NULL };
printf("\n%s\n",son[1]);
x = direct_pos + 2;
pid_t pid = fork();
if (pid == 0) {
execvp(son[0], son)==-1);
break;
}
} else if (strcmp(name, direc[x]) == 0) {
x = direct_pos + 2;
}
}
}
}
sleep(IterationTime);
actual_time += IterationTime;
closedir(dirp);
}
exit(0);
}
答案 0 :(得分:2)
你有一个程序可以分叉然后运行它自己的新副本。把它想象成无休止的递归。无需执行新实例,只需编写代码,以便程序根据返回的进程ID继续执行两个路径之一。
但这不是正确的解决方案。
正确的解决方案根本不是分叉。拥有一千个查看一个目录的进程,而不是查看一千个目录的单个进程,几乎没有任何好处。实际上,通过在调度程序上加载负载可能会更糟糕。
答案 1 :(得分:1)
看起来你无论如何总是叉。我会在那里放一张支票,以确保如果当前目录中没有子目录,那么你就不用叉子。
答案 2 :(得分:0)
你正在分配一个子进程,但是在调用fork()?
之后父进程做了什么似乎你想要递归地分叉进程,但是为了使它正常工作,你将不得不 - 如下:
1)检查当前目录中是否有子目录...如果没有,则exit()
,否则读取当前目录中的所有子目录。
2)为每个子目录分叉一个进程。如果分叉是孩子(即pid == 0
),则拨打execvp()
。
3)如果是pid != 0
,那么您就在父进程中。而不是试着睡一段时间,打电话给wait()
,并继续重复调用wait()
,直到没有子进程离开。
4)一旦没有剩下子进程(即wait()
返回错误状态,使errno == ECHILD
),那么您可以在父进程中调用exit()
因此,如果您遵循这4个步骤,则不应该产生任何无限循环。每个子进程一旦到达不再有子目录的目录就会在某个时刻退出,并且每个父进程在退出之前都会等待它的子进程,这样您就不会得到任何孤立的进程。如果你最终得到一个无限循环,那是因为子进程没有退出,这将指向用于检测当前目录中是否有任何子目录的逻辑,或者你没有正确检测到在父进程中不再有任何孩子等待。
希望这有帮助,
杰森