如何使多个子进程递增并跟踪相同的全局变量

时间:2019-03-31 18:38:42

标签: c unix recursion fork posix

我的任务是制作一个程序,该程序分析文件/目录并提供有关它们的信息。您可以设置一个递归标志来分析每个子目录。每个目录都由一个新过程进行分析(这是项目的要求),我想在每次找到新文件(SIGUSR2)或目录(SIGUSR1)时发送信号。在这些信号的处理程序中,我想增加全局变量,以跟踪程序找到的文件/目录的数量。我在使不同的进程递增相同的全局变量时遇到问题。我尝试过管道,但似乎无法正常工作。

这是我分析目录的函数:

void process_dir(const ProgramConfig program_config, const char *dname, FILE *outstream)
{

  raise(SIGUSR1);

  /* Create a new process */
  pid_t pid = fork();

  if (pid == 0)
  {

    /* Child process */
    struct dirent *ent;
    DIR *dir;

    /* Open directory */
    if ((dir = opendir(dname)) != NULL)
    {
      /* Go through each file in this directory */
      while ((ent = readdir(dir)) != NULL)
      {
        /* Ignore anything that isn't a file or a directory */
        if (ent->d_type != DT_DIR && ent->d_type != DT_REG)
          continue;

        /* Ignore the '.' and '..' directories */
        if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
          continue;

        /* Prepend this directory name to file name */
        char name[256];
        strcpy(name, dname);
        strcat(name, "/");
        strcat(name, ent->d_name);

        if (ent->d_type == DT_DIR && program_config.r_flag)
        {
          /* Found a subdirectory, process it if -r flag enabled */
          process_dir(program_config, name, outstream);
        }
        else
        {
          /* Found a file, process it */
          process_file(program_config, name, outstream);
        }
      }
    }
    else
    {
      /* Error opening directory */
    }

    /* Exit from child process */
    exit(0);
  }
  else if (pid < 0)
  {
    /* Error creating process */
  }
  else
  {

    /* Parent process */
    wait(NULL);

    /* Log this event */
    if (program_config.v_flag)
    {
      char act[100];
      sprintf(act, "PROCESSED DIR %s", dname);
      log_event(act);
    }
  }
}

这是我的处理程序:

void sigusr1_handler(int sig)
{
  if (sig != SIGUSR1)
  {
    fprintf(stderr, "Wrong signal received! Expected: SIGUSR1\n");
  }

  dirsFound++;
  printf("New directory: %ld/%ld directories/files at this time.\n", dirsFound, filesFound);
}

void sigusr2_handler(int sig)
{
  if (sig != SIGUSR2)
  {
    fprintf(stderr, "Wrong signal received! Expected: SIGUSR2\n");
  }

  filesFound++;
}

使用线程不是此分配的选项。

3 个答案:

答案 0 :(得分:0)

如果每个子进程都发送信号,则无需共享计数器或“全局”计数器。捕获来自子代的所有信号的信号处理程序可以对其进行递增。如果程序中没有其他部分需要检查,则它可以是static局部变量。如果没有,它可能会被所有具有获取和设置它的功能的模块声明为static

如果您希望多个进程递增同一共享变量,则需要将<stdatomic.h>中的原子变量(例如atomic_int)放入共享内存中,您可以从{{ 1}},并用shmget()递增。

我不会写一个完整的解决方案,因为听起来您想自己解决这个家庭作业问题。

答案 1 :(得分:0)

如果我理解正确的话,可以按照引发信号的相同过程来处理信号。结果,每个后代进程都会递增其自己的在特定子目录中找到的目录和文件的计数器。您需要做的是将最高祖先进程ID传递给其所有后代,并从后代向最高祖先发送信号。有关将信号发送到另一个进程的提示,请参见How to send a signal to a process in C?

答案 2 :(得分:0)

您可以使用我认为的命名信号量:

https://www.systutorials.com/docs/linux/man/7-sem_overview/

基本上在各个进程中打开具有相同名称的信号量,使用sem_post递增,使用sem_getvalue获取值。