程序在print和if语句之间停止进行

时间:2016-03-27 06:02:43

标签: c process fork semaphore shared-memory

我正在实现使用共享内存的问题的解决方案,但不知何故,我的代码似乎在print语句和if语句之间“冻结”。

以下是相关的代码段:

#include "ch_problem_headers.h"
int main(int argc, char *argv[])
{
  int semid, shmid;
  int i;
  int waiting_C, waiting_H = 0; // shared
  int c_pid,h_pid;
  time_t t;
  // There should be three semaphores: S for when to pass the molecule on,
  // SC for the carbon waiting, and SH for the hydrogen waitin

  unsigned short seminit[NUM_SEMS];
  struct common *shared;
  union semun semctlarg;

  srand((unsigned)time(&t));

  if((semid = semget(IPC_PRIVATE, NUM_SEMS, IPC_CREAT|0777)) < 0)
  {
    perror("semget");
    exit(EXIT_FAILURE);
  }

  // Initialize semaphores
  seminit[S_SEM] = 1;
  seminit[SC_SEM] = 0;
  seminit[SH_SEM] = 0;
  semctlarg.array = seminit;

  // Apply initialization
  if((semctl(semid, NUM_SEMS, SETALL, semctlarg)) < 0)
  {
    perror("semctl");
    exit(EXIT_FAILURE);
  }

  // Get shared memory id
  if((shmid = shmget(IPC_PRIVATE, 1*K, IPC_CREAT|IPC_EXCL|0660)) < 0)
  {
    perror("shmget");
    exit(EXIT_FAILURE);
  }

  // Retrieve pointer to shared data structure
  if((shared = (struct common *)shmat(shmid, 0, 0)) < 0)
  {
    perror("shmat");
    exit(EXIT_FAILURE);
  }

  shared->waiting_C = 0;
  shared->waiting_H = 0;

  printf("ready to fork\n");
  // fork process C
  c_pid = fork();
  printf("c_pid is %d\n", c_pid);
  if(c_pid == 0)
  {
    printf("I'm process C!/n");
    // wait on S
    semWait(semid, S_SEM);
    // if waiting_H >= 4
    if(shared->waiting_H >= 4)
    {
      //    signal SH four times
      for(i = 0; i < 4; i++)
      {
        semSignal(semid, SH_SEM);
        printf("H");
      }
      //    Decrement waiting_H by 4
      shared->waiting_H -= 4;
      //    Signal S
      semSignal(semid, S_SEM);
    }
    // Otherwise, increment waiting_C by 1
    else
    {
      shared->waiting_C += 1;
      //      Signal S and wait for SC
      semSignal(semid, S_SEM);
      semWait(semid, SC_SEM);
    }
  }
  else
  {
    printf("C's process id is %d\n", c_pid);

    printf("ready to fork again\n");
    // fork process H
    h_pid = fork();
    printf("Is h_pid zero? %d\n", (h_pid == 0));
    if(h_pid == 0)
    {
      printf("I'm process H!/n");
      // Wait on S
      semWait(semid, S_SEM);
      // If waiting_h >= 3
      if(shared->waiting_H >= 3)
      {
        //   Signal SH three times, decrement waiting_H by 3, signal SC, decrement
        for(i = 0; i < 3; i++)
        {
          printf("H");
          semSignal(semid, SH_SEM);
        }
        shared->waiting_H -=3;
        semSignal(semid, SC_SEM);
        shared->waiting_C -= 1;
        semSignal(semid, S_SEM);
        //   waitng_C by 1, and signal S
      }
      // Otherwise, increment waiting_H by 1, signal S, and wait on SH
      else
      {
        shared->waiting_H += 1;
        semSignal(semid, S_SEM);
        semWait(semid, SH_SEM);
      }
    }
    else
    {
      printf("In the parent\n");
    }
  }
}

相关的头文件:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#define K 1024

#define NUM_SEMS 3
#define SEMKEY 77
#define SHMKEY 77

#define S_SEM 0
#define SH_SEM 1
#define SC_SEM 2

#define NUM_H 4
#define NUM_C 1

union semun
{
  unsigned short *array;
};

struct common
{
  int waiting_C;
  int waiting_H;
};

void semWait(int semid, int semaphore)
{
  struct sembuf psembuf;

  psembuf.sem_op = -1;
  psembuf.sem_flg = 0;
  psembuf.sem_num = semaphore;
  semop(semid, &psembuf, 1);
  return;
}

void semSignal(int semid, int semaphore)
{
  struct sembuf vsembuf;

  vsembuf.sem_op = 1;
  vsembuf.sem_flg = 0;
  vsembuf.sem_num = semaphore;
  semop(semid, &vsembuf, 1);
  return;
}

运行时的程序输出如下:

父输出(正确):

准备分叉

c_pid是2977

C的流程ID是2977

准备再次分叉

h_pid是否为零? 0

在父母

儿童输出:

h_pid是否为零? 1

c_pid为0

我尝试在valgrind中运行程序,程序在子输出后暂停。我很困惑这是如何可能的,因为程序似乎只是在c_pid print语句和if(c_pid == 0)语句之间停止。

有没有人知道为什么会这样?非常感谢。

0 个答案:

没有答案