【问题标题】:why is the fork() function in my code not creating a child process?为什么我的代码中的 fork() 函数没有创建子进程?
【发布时间】:2018-12-29 13:58:09
【问题描述】:

我正在尝试编写一个程序,该程序采用命令行参数来验证日期,然后显示在该日期之后修改的所有文件。由于某种原因,fork() 函数似乎没有创建子进程,也没有执行相应的代码部分,我不知道为什么。有什么建议吗?

fork() 部分本身位于第 59 和 76 行。其余代码运行良好,但 findafterdate() 函数仅对父进程执行。

 1 #define _XOPEN_SOURCE
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <string.h>
 5 #include <time.h>
 6 #include <sys/wait.h>
 7 #include <unistd.h>
 8 #include <sys/types.h>
 9 #include <sys/stat.h>
10 #include <pthread.h>
11 char date[255];
12 char startLoc[255];
13
14
15 int findafterdate(int pid, char startLocation);
16
17
18
19 int main(int argc, char* argv[]){
20     //check arguments have been used
21
22     if(argc <2){
23         fprintf(stderr, "ERROR -- no argument set. use -h for help\n");
24         exit(EXIT_FAILURE);
25     }
26
27     //check for help switch
28     if (strcmp(argv[1], "-h")==0){
29         printf("usage: %s -t \"YYYY-MM-DD hh:mm:ss\"\n", argv[0]);
30         exit(EXIT_SUCCESS);
31     }
32     //check for cutoff time switch
33     else if(strcmp(argv[1], "-t")==0){
34       //check correct argument was used
35       if (argc <= 2){
36          fprintf(stderr, "ERROR -- use the format: %s -t \"YYYY-MM-DD hh:mm:ss\"\n", argv[0]);
37          exit(EXIT_FAILURE);
38       }
39       //set global variable startLoc to argv[3], or "." if none has been given
40       if (argc <= 3){
41         printf("test");
42         strncpy(startLoc, ".", sizeof(startLoc));
43         printf("start location automatically set to launch directory\n");
44       }
45       else{
46         printf("test");
47         strncpy(startLoc, argv[3], sizeof(startLoc));
48         printf("start location set to %s\n", startLoc);
49       }
50       //check if a filename was given
51
52       if ((strncmp(argv[2], "2", 1)!=0)){
53         printf("filename identified\n");
54         struct stat filestat;
55         stat(("%s", argv[2]), &filestat);
56         printf("%s", ctime(&filestat.st_mtime));
57         strncpy(date, ("%s", ctime(&filestat.st_mtime)), sizeof(date));
58         pid_t pid;
59         pid = fork();
60         findafterdate(pid, *startLoc);
61         return 0;
62       }
63
64       //check length of string to determine whether correct YYYY-MM-DD hh:mm:ss format was used
65       else if (strlen(argv[2]) <16 || strlen(argv[2])>19){
66         fprintf(stderr, "ERROR -- Invalid date format\n");
67         exit(EXIT_FAILURE);
68       }
69       //re - format argument into tm
70       struct tm tm;
71
72       memset(&tm, 0, sizeof(struct tm));
73       strptime(argv[2], "%Y-%m-%d %H:%M:%S", &tm);
74       strftime(date, sizeof(date), "%b %d %Y %H:%M", &tm);
75       pid_t pid;
76       pid = fork();
77       findafterdate(pid, *startLoc);
78       return 0;
79     }
80 }
81 int findafterdate(int pid, char startLocation){
82     if (pid==0){
83 //      printf("child check");
84         printf("start location: %s || date : %s\n", startLocation, date);
85         execl("/usr/bin/find", "find",("%s", startLocation), "-newermt", ("%s", date), NULL);
86     }
87     else{
88         printf("listing files modified after: %s\n", date);
89         int status;
90         waitpid(pid, &status, 0);
91     }
92     return EXIT_SUCCESS;
93   }
                                                                                                                                                                                             62,2-5        Bot

子进程应该在执行“find -newermt”之前打印“child check”(这是为了确保在实际进程中没有出现段错误),以显示起始目录下的所有文件在之后修改给定的日期。相反,它根本什么都不做。我终其一生都无法弄清楚这是为什么。

【问题讨论】:

  • 那么fork() 会返回什么?您永远不会检查任何错误。
  • 尝试在execl() 之前添加fflush(stdout);。还要检查后一个函数的错误。它里面的 ("%s", blah) 东西应该做什么?您真的要使用逗号运算符吗?
  • 在展示源代码时,不要包含行号。行号使我们很难自己使用它,从而使包含代码的目的达不到一半。如果您想引起我们对特定行的注意,那么有更好的方法可以做到这一点,例如插入专用的 cmets。
  • @Shawn 我会尝试检查错误,但我认为这不是问题,因为fork() 似乎根本没有创建子进程。至于("%s" , blah) 的东西,我是一名学生,对 C 语言非常陌生,这是迄今为止我弄清楚如何在参数中使用字符串的唯一方法。如果你能告诉我一个更好的方法,将不胜感激。
  • findafterdate() 中,startLocationchar,但作为与%s 格式描述符对应的参数传递给printf(),其中需要char *。编译器应该已经警告过你了;尝试在打开警告的情况下进行编译。因此,程序的行为是不确定的。

标签: c fork pid child-process


【解决方案1】:

findafterdate() 中,startLocationchar,但作为与%s 格式描述符对应的参数传递给printf(),其中需要char *。编译器应该已经警告过你了;尝试在打开警告的情况下进行编译。因此,程序的行为是不确定的。

未定义的行为是未定义的,没有可以说明程序的操作。

附:对execl() 的调用非常奇怪。您认为("%s", startLocation) 与普通startLocation 有何不同? execl() 的参数必须是 char * 而不是 char

【讨论】:

  • 已经解决了,谢谢!我在之前的评论中说过,我是学生;我只使用 c 几个星期,而且我对一般的编程没有太多经验。 %s 描述符是我发现将字符串传递给函数而不会出现编译错误的唯一方法。我知道这很麻烦,但是在为作业编写代码方面,我的主要目标是让事情运行起来,所以我至少有一个工作程序要提交。在我知道我至少有一些可以依靠的东西之后,我通常会回去提高可读性。再次感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 2012-08-02
  • 1970-01-01
  • 2021-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多