使用shmctl()销毁共享内存段(Linux)

时间:2013-11-12 20:50:02

标签: c linux shared-memory semaphore producer-consumer

我很难搞清楚这一点。我有一些使用信号量的生产者/消费者问题的代码建模(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
     }
  }
}

1 个答案:

答案 0 :(得分:2)

您正在分离NULL指针。您需要分离shmat()返回的地址。此外,您可能希望将片段标记为在其创建的位置进行销毁,退出也可以处理分离,这样可以减少意外发生时内存 limbo'd 的可能性。您可能仍应手动分离。

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

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

// ...do stuff...

// detach.
shmdt(buffer);