C - 创建两个可以生成奇数和偶数整数的进程

时间:2015-02-18 19:40:12

标签: c process operating-system fork sleep

我有这个任务,我必须创建两个进程,每个进程必须生成50个奇数或偶数的整数。

  

编写一个简单的序列号系统,通过该系统,两个进程P1和P2每个都可以获得50个唯一的整数,这样一个接收所有奇数,另一个接收所有偶数。使用fork()调用来创建P1和P2。给定包含单个数字的文件F,每个进程必须执行以下步骤:

  一个。打开F.
  湾从文件中读取序列号N   C。关闭F.
  d。输出N和过程'PID(在屏幕或测试文件上)   即增加N乘以1   F。打开F.
  G。将N写入F.
  H。冲洗F.
  一世。关闭F

作为suggested by SO user我在每个进程中创建了一个循环并运行上述步骤。但我不确定这种方法是否正确。我已经向我的助教求助了,他建议做同样的事情(使用睡眠呼叫并等待有效的整数)。但问题是我可以在不使用睡眠呼叫的情况下获得相同的结果。所以我不确定我是否正确地将逻辑应用于代码。有人可以帮忙吗?

这是我的实施:

void getUniqueNumbers() {

    struct process p1;
    struct process p2;
    int numberFromFile;

    pid_t pid = fork();

    // Process 1
    if (pid == 0) {

        int p1Counter = 0;
        p1.processId = getpid();

        while(p1Counter < numLimit) {
            numberFromFile = getNumberFromFile();
            if (numberFromFile % 2 == 0) { // even
                p1.numbers[p1Counter] = numberFromFile;
                printf("N: %d, PID: %d\n", numberFromFile, p1.processId);
                numberFromFile++;
                writeNumberToFile(numberFromFile);
                p1Counter++;
            }
            else {
                sleep(1);
            }

        }

    }
    // Process 2
    else if (pid > 0 ) {

        int p2Counter = 0;
        p2.processId = getpid();

        while(p2Counter < numLimit) {
            numberFromFile = getNumberFromFile();
            if (numberFromFile % 2 != 0) { // odd
                p2.numbers[p2Counter] = numberFromFile;
                printf("N: %d, PID: %d\n", numberFromFile, p2.processId);
                numberFromFile++;
                writeNumberToFile(numberFromFile);
                p2Counter++;
            }
            else {
                sleep(1);
            }
        }

    }
    else {
        printf("Error: Could not create process\n");
    }

}

读/写功能:

// Returns the number included in user provided file
int getNumberFromFile() {

    FILE *fp = fopen(fileName, "rb");
    int num = 0;

    if (fp != 0) {
        char line[10];
        if (fgets(line, sizeof(line), fp) != 0)
            num = atoi(line);
        fclose(fp);
    }

    return num;

}

// Writes a given number to the user provided file
void writeNumberToFile(int num) {

    FILE *fp = fopen(fileName, "w");

    if (fp != 0) {
        fprintf(fp, "%d", num);
        fclose(fp);
    }

}

1 个答案:

答案 0 :(得分:0)

代码看起来不错。它可以简化很多。

void getUniqueNumbers()
{
  struct process p;       // We need only 1 structure
  size_t counter = 0;     // sample counter
  int    oddEven;         // flag if we are parent
  pid_t pid = fork();     // Fork here
  if (-1 == pid)
  {
    abort(); // simply die on error
  }

  oddEven = 0 == pid ? 0 : 1;
  p.processId = getpid(); // We are either child or parent.

  while (counter < numLimit)
  {
    int numberFromFile = getNumberFromFile();
    if ((numberFromFile & 1) == oddEven)
    {
      p.numbers[counter++] = numberFromFile;
      printf("N: %d, PID: %ld\n", numberFromFile, (long)p.processId);
      numberFromFile++;
      writeNumberToFile(numberFromFile);
    }
    sleep(1); // sleep in both cases
    // Extra check for parent: if child has died, we are in infinite
    // loop, so check it here
    if (0 != pid && counter < numLimit)
    {
      int status = 0;
      if (waitpid(pid, &status, WNOHANG) > 0)
      {
        printf("Child exited with 0x%08X status\n", status);
        break;
      }
    }
  }

  // wait till child process terminates
  if (0 != pid)
  {
    int status = 0;
    waitpid(pid, &status, 0);
    printf("Child exited with 0x%08X status\n", status);
  }
}

此外,文件读/写应使用文件锁操作或原子文件更改。重要的是要防止潜在的错误,例如一个线程正在写入编号40006,而另一个线程则设法读取400.尽管不应该在现实生活中发生。

需要文件锁来防止对相同内容的并发访问。它可以是独占锁,也可以是共享读独占写。

原子修改是一种能够以原子方式替换文件内容的功能,无论编写数据所花费的操作数量多少。它是保持数据一致的替代方案。