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

标签 c process operating-system fork sleep

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

Write a simple sequence-number system through which two processes, P1 and P2, can each obtain 50 unique integers, such that one receives all the odd and the other all the even numbers. Use the fork() call to create P1 and P2. Given a file, F, containing a single number, each process must perform the following steps:

a. Open F.
b. Read the sequence number N from the file.
c. Close F.
d. Output N and the process' PID (either on screen or test file).
e. Increment N by 1
f. Open F.
g. Write N to F.
h. Flush F.
i. Close F

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

这是我的实现:

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);
    }

}

最佳答案

代码看起来没问题。不过它可以简化很多。

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。但这在现实生活中不应发生。

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

原子修改是一种能够自动替换文件内容的功能,无论写入数据需要进行多少次操作。它是保持数据一致性的另一种选择。

关于C - 创建两个可以生成奇数和偶数的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28592437/

相关文章:

linux - Fedora Gnome 突然出现高 CPU 使用率

c - 从子进程中获取父进程 ID

linux - 使用系统调用造成缓存污染

java - 在抽象语法树中一个接一个地插入节点 - Eclipse CDT

CMSIS DSP 库中的复杂点积

objective-c - 改变 RGB 颜色的色调

c - 为什么 "typedef struct foo foo;"被认为是有害的?

c# - 我正在尝试使用以下代码片段在 C# 中运行 R 脚本。但是输出会重复

c/unix : abort process that runs for too long

multithreading - 对于CPU调度或中断,CPU会不会执行完当前指令?