1

我很难弄清楚这一点。我有一些代码对使用信号量的生产者/消费者问题进行建模(P() 和 V() 分别只是通常的 wait() 和 signal() 函数)。

我为实现中使用的缓冲区分配了一些内存,但我不明白程序退出后如何正确销毁分配的空间。这会在我第二次运行程序时产生问题,旧数据要么保留在内存中,要么甚至弹出一个错误,不允许我再次分配共享空间。

这是代码:

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

#include "sem.h"


#define N 3
#define BUFSIZE 1  
#define PERMS 0666 //0666 - To grant read and write permissions 

int *buffer;
int nextp=0,nextc=0;
int mutex,full,empty;    /* semaphore variables
                          * mutex - binary semaphore -- critical section
                          * full, empty - counting semaphore */

void producer()
{
 int data;
 if(nextp == N)
    nextp=0;
 printf("\nEnter the data(producer) :");
 scanf("%d",(buffer+nextp));
 nextp++;
 }

void consumer()
{
 int g;
 if(nextc == N)
    nextc=0;
 g=*(buffer+nextc++);
 printf("\nconsumer consumes the data:%d\n",g);
}

int main()
{
 int shmid,no=1,i;
 int pid,n;

 if((shmid=shmget(1000,BUFSIZE,IPC_CREAT | PERMS)) < 0)
 {
  printf("\n unable to create shared memory");
  return;
 }
 if((buffer=(int*)shmat(shmid,(char*)0,0)) == (int*)-1)
 {
  printf("\n Shared memory allocation error\n");
  exit(1);
 }

 // semaphore creation
 if((mutex=semget(IPC_PRIVATE,1,PERMS | IPC_CREAT)) == -1)
 {
   printf("\n can't create mutex semaphore");
   exit(1);
 }

 if((empty=semget(IPC_PRIVATE,1,PERMS | IPC_CREAT)) == -1)
 {
  printf("\n can't create empty semaphore");
  exit(1);
 }

 if((full=semget(IPC_PRIVATE,1,PERMS | IPC_CREAT)) == -1)
 {
  printf("\ncan't create full semaphore");
  exit(1);
 }

 // initialze the semaphore     
 sem_create(mutex,1);
 sem_create(empty,N);
 sem_create(full,0);


//forking a child 
 if((pid=fork()) < 0)
 {
  printf("\n Error in process creation");
  exit(1);
 }

//Producer process
 if(pid > 0)
 {
    for(i=0;i<N;i++)
    {
      P(empty); 
      P(mutex); // Entering critical section
      producer();
      V(mutex); // Exit from critical section
      V(full); 
    }
    wait();
    semkill(mutex);
    semkill(empty);
    semkill(full);
    shmdt(0);
    shmctl(shmid, IPC_RMID, NULL);
 }

//consumer process
    if(pid == 0)
    {
     for(i=0;i<N;i++)
     {
      P(full);
      P(mutex); // Entering critical section
      consumer();
      V(mutex);
      V(empty); // Exit from critical section
     }
  }
}
4

1 回答 1

2

你正在分离一个NULL指针。您需要分离返回的地址shmat()。此外,您可能希望将段标记为在创建它的位置进行销毁,这样 exit 也可以处理分离,这减少了在意外发生时内存陷入困境的机会。您可能仍然应该手动分离。

// ...create shared memory segment...

// attach.
buffer = shmat(shmid, 0, 0);
// mark for destruction.
shmctl(shmid, IPC_RMID, 0);

// ...do stuff...

// detach.
shmdt(buffer);
于 2014-03-18T15:15:24.820 回答