如何获取sem_wait()的返回值?

时间:2014-03-12 00:57:19

标签: c process posix semaphore

我有一个程序,它应该允许两个进程在执行某个任务之间交替。在子进程第五次执行其任务之后,它必须销毁一个信号量,并且父进程应该因为它而停止。

这听起来相当容易,但我很难捕获sem_wait()函数的返回值。

这是我的档案:

#include "Part2Defs.h"

int main() {

  FILE *fptr = 0;

  sem_t *child  = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
                       MAP_SHARED|MAP_ANONYMOUS, -1, 0);

  sem_t *parent = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
                 MAP_SHARED|MAP_ANONYMOUS, -1, 0);

  /* save the number that we'll be writing to the file */
  int number = 1, removed = 0;

  sem_init(child,  1, 1);
  sem_init(parent, 1, 0);


  fptr = fopen(BUFFER, "r+");
  if(fptr == 0) {
    printf("An error occurred while opening the file\n");
  }

  fprintf(fptr, "%d", number);

  fclose(fptr);

  int pID = fork();

  if(pID == 0) {

    /* do this FOREVER. */
    while(1) {

      /* I was hoping to get the return value here */
      if(sem_wait(parent) == 0) {

      /* open the file */
      fptr = fopen(BUFFER, "r+");

      printf("B. The number [] was modified by parent\n");

      fclose(fptr);
      sem_post(child);
      }
      else {
        printf("--parent-- waiting for new number to be READ: Identifier removed");
      }
    } 

    return 0;
  }
  else if(pID > 0) {

    /* make a counter to go from 0 to 5 */
    int i = 0;
    while(1) {

      sem_wait(child);

     if(i++ == 5) {
        /* delete the semaphore */
        sem_destroy(parent);

        printf("Semaphore removed\n");
        break;
      }
       /* open the file */
      fptr = fopen(BUFFER, "r+");

      printf("A. The number [] was modified by child\n");

      fclose(fptr);
      sem_post(parent);
   }

    return 0;
  }
  else {
    printf("There was an error creating the fork.\n");
    exit(1);
  }
}

这是我的输出:

A. The number [] was modified by child
B. The number [] was modified by parent
A. The number [] was modified by child
B. The number [] was modified by parent
A. The number [] was modified by child
B. The number [] was modified by parent
A. The number [] was modified by child
B. The number [] was modified by parent
A. The number [] was modified by child
B. The number [] was modified by parent
Semaphore removed

这几乎正是我所希望的,除了父进程永远不会以包含错误的消息结束。

顺便说一句:这是家庭作业,但由于我缺乏声誉,我不应该在自己的帖子上添加家庭作业标签。

2 个答案:

答案 0 :(得分:0)

sem_wait的返回值仅反映其获取锁定的失败/失败。如果要在进程之间进行通信,则需要其他机制(例如,共享内存)。

答案 1 :(得分:0)

http://man7.org/linux/man-pages/man3/sem_destroy.3.html

“销毁其他进程或线程当前的信号量        阻塞(在sem_wait(3)中)产生未定义的行为。“

我找到了一种方法,可以使用其中一个信号量作为标志来告诉父母何时完成。

#include "Part2Defs.h"


int main() {

  FILE *fptr = 0;

  sem_t *child  = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
                       MAP_SHARED|MAP_ANONYMOUS, -1, 0);

  sem_t *parent = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
                 MAP_SHARED|MAP_ANONYMOUS, -1, 0);

  /* save the number that we'll be writing to the file */
  int number = 1, removed = 0;

  sem_init(child,  1, 0);
  sem_init(parent, 1, 0);


  fptr = fopen(BUFFER, "r+");
  if(fptr == 0) {
    printf("An error occurred while opening the file\n");
  }

  fprintf(fptr, "%d", number);

  fclose(fptr);

  int pID = fork();

  if(pID == 0) {

    /* do this FOREVER. */
    while(1) {
      sem_post(child);
      sem_wait(parent);
      if(!sem_trywait(child))
          break;
      /* open the file */
      fptr = fopen(BUFFER, "r+");

      printf("B. The number [] was modified by parent\n");
      fflush(stdout);

      fclose(fptr);
    }

    sem_destroy(child);
    sem_destroy(parent);

    printf("--parent-- waiting for new number to be READ: Identifier removed");
    return 0;
  }
  else if(pID > 0) {

    /* make a counter to go from 0 to 5 */
    int i = 0;
    while(1) {
      sem_wait(child);

     if(i++ == 5) {
        sem_post(child);
        sem_post(parent);
        //Signal the parent that it's done by adding one to child.

        printf("Semaphore removed\n");
        break;
      }
       /* open the file */
      fptr = fopen(BUFFER, "r+");

      printf("A. The number [] was modified by child\n");
      fflush(stdout);

      fclose(fptr);

      sem_post(parent);
   }

    return 0;
  }
  else {
    printf("There was an error creating the fork.\n");
    exit(1);
  }
}