2013-11-12 3 views
1

У меня возникли проблемы с этим. У меня есть код, моделирующий проблему «Продюсер/потребитель», которая использует семафоры (P() и V() - это обычные функции wait() и signal(), соответственно).Уничтожение сегмента разделяемой памяти с помощью shmctl() (Linux)

Я выделяю некоторую память для буфера, который я использую в реализации, но я не понимаю, как правильно уничтожить выделенное пространство после выхода программы. Это создает проблемы, когда я запускаю программу во второй раз, когда либо старые данные остаются в памяти, либо даже появляется всплывающая подсказка, которая не позволяет мне снова распределять общее пространство.

Вот код:

#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 
    } 
    } 
} 
+0

У вас есть особая причина, что вы используете старенькую 'shmget' и т.д. функцию и не проще использовать комбинацию' 'shm_open' и mmap'? –

+0

Нет, просто ушел с образца, который у меня был. Это мой первый опыт работы с этими библиотеками. – Mike

ответ

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); 
Смежные вопросы