【问题标题】:C - create two processes which can generate odd and even integersC - 创建两个可以生成奇数和偶数整数的进程
【发布时间】:2015-04-19 23:23:57
【问题描述】:

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

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

一种。打开 F.
湾。从文件中读取序号 N。
C。关闭 F.
d。输出 N 和进程的 PID(在屏幕上或测试文件上)。
e.将 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);
    }

}

【问题讨论】:

  • 可以添加 read/writeNumber 函数的实现吗?
  • @ValeriAtamaniouk 已添加
  • 您的读/写打开操作有点不一致:两者都应该使用文本模式来正确处理换行符。

标签: c process operating-system fork sleep


【解决方案1】:

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

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

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

原子修改是一种能够以原子方式替换文件内容的功能,无论写入数据需要多少操作。它是保持数据一致的替代方法。

【讨论】:

    猜你喜欢
    • 2020-02-28
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多