1

我将尽我所能在我所拥有的理解下提出这个问题。

我正在做一个编程任务(现在让我们把它搞定),它在 Unix 服务器上使用 C 或 C++ 来分叉四个孩子,并使用信号量和共享内存来更新全局变量。我不确定我是否有问题,但我缺乏理解让我质疑我的结构。这里是:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define NUM_REPEATS 10
#define SEM_KEY  1111
#define SHM_KEY  2222

int globalCounter = 0;

/***** Test function for confriming a process type ******/
int checkProcessType(const char *whoami)
{
  printf("I am a %s.  My pid is:%d  my ppid is %d\n",
  whoami, getpid(), getppid() );
  for(int i = 1; i<=3; i++){
    printf("%s counting %d\n", whoami, i);
  }
  return 1;
}

void 

int main (void) {

  pid_t process_id;       // PID (child or zero)
  int sharedMemID;        // Shared memory ID
  int sharedMemSize;      // shared memory size
  struct my_mem * sharedMemPointer;   // pointer to the attached shared memory

  // Definition of shared memory  //
  struct my_mem {
    long counter;
    int parent;
    int child;
  };

  // Gathering size of shared memory in bytes //
  sharedMemSize = sizeof(my_mem);
  if(sharedMemSize <= 0){
    perror("error collection shared memory size: Exiting...\n");
    exit(0);
  }

  // Creating Shared Memory //
  sharedMemID = shmget(SHM_KEY, sharedMemSize, 0666 | IPC_CREAT);
  if (sharedMemID < 0) {
    perror("Creating shared memory has failed: Exiting...");
    exit(0);
  }

  // Attaching Shared Memory //
  sharedMemPointer = (struct my_mem *)shmat(sharedMemID, NULL, 0);
  if (sharedMemPointer == (struct my_mem*) -1) {
    perror("Attaching shared memory has failed. Exiting...\n");
    exit(0);
  }

  // Initializing Shared Memory //
  sharedMemPointer->counter = 0;
  sharedMemPointer->parent = 0;
  sharedMemPointer->child = 0;

  pid_t adder, reader1, reader2, reader3;
  adder = fork();
  if(adder > 0)
  {
    // In parent

    reader1 = fork();
    if(reader1 > 0)
    {
      // In parent

      reader2 = fork();
      if(reader2 > 0)
      {
        //In parent

        reader3 = fork();
        if (reader3 > 0)
        {
          //In parent

        }
        else if (reader3 < 0)
        {
          // Error
          perror("fork() error");
        }
        else
        {
          // In reader3

        }
      }
      else if(reader2 < 0)
      {
        //Error
        perror("fork() error");
      }
      else
      {
        // In reader2

      }
    }
    else if(reader1 < 0)
    {
      // Error
      perror("fork() error");
    }
    else
    {
      // In reader1

    }
  }
  else if(adder < 0 )
  {
    // Error
    perror("fork() error");
  }
  else
  {
    // In adder
    //LOOP here for global var in critical section
  }


}

只是我在做什么的一些信息(我认为),我正在创建一个包含一个变量的共享内存块,让我们称之为它将由父级counter严格更新,adder在所有子进程之后成为减法器是活跃的。我仍在尝试找出我将使用的信号量内容,以便加法器和减法器在关键部分执行,但我的主要问题是这个。

我怎么知道我在这个结构中的位置?我的加法器应该有一个循环来完成一些工作(更新全局变量),并且父/减法器应该有一个循环来完成它的工作(也更新全局变量)。并且readers可以随时查看。父/减法器的循环放置是否重要?我基本上有 3 个地点,我知道我会在父母那里。但是由于所有孩子都需要首先创建,所以它必须在我知道我在父母中的第三次分叉之后的最后一个条件中吗?当我使用我的测试方法时,我得到分散的输出,这意味着孩子一可以在父母的输出之后,然后是孩子三,等等。它从来没有任何顺序,根据我对 fork 的理解,这是预期的。

我真的有三个问题要问,但我需要先了解一下这个结构。所以让我试着简洁地说一遍,没有任何垃圾,因为我挂在循环和关键部分的位置上,甚至还没有写出来。

更直接地说,父母什么时候知道所有孩子的存在,并且通过这种结构,一个孩子可以做一个任务并以某种方式回到它(即加法器/第一个孩子添加到全局变量一次,退出,并且其他一些孩子可以做它的事情ETC)。

我仍然觉得我没有问正确的事情,我相信这是由于仍在尝试掌握概念。希望我的口吃能说明我在概念上的坚持。如果不是我可以澄清。

4

0 回答 0