首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C-创建两个可生成奇数整数和偶数整数的进程。

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

Stack Overflow用户
提问于 2015-02-18 19:40:11
回答 1查看 1.7K关注 0票数 0

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

编写一个简单的序列号系统,通过这个系统,两个进程,P1和P2,可以分别获得50个唯一的整数,例如一个接收所有奇数,另一个接收所有偶数。使用fork()调用来创建P1和P2。给定一个包含单个数字的文件F,每个进程必须执行以下步骤: a. Open F。 从文件中读取序列号N。 c.关闭F. 输出N和进程PID (无论是在屏幕上还是在测试文件上)。 e. N增加1 f.打开F. g.把N写到F。 h.冲洗F. 一.关闭F

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

这就是我的实现:

代码语言:javascript
运行
复制
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");
    }

}

读写功能:

代码语言:javascript
运行
复制
// 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);
    }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-18 21:18:07

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

代码语言:javascript
运行
复制
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个线程。但不应该发生在现实生活中。

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

原子修改是一种特性,可以原子地替换文件内容,而不管写入数据所需的操作有多少。这是保持数据一致性的另一种选择。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28592437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档