2013-02-03 4 views
2

아래 프로그램은 "shmid"위치의 공유 메모리에 액세스하여 "total"포인터에 연결합니다. 그런 다음이 메모리 조각을 액세스하고 수정 한 다음 완료되면 다른 자식 프로세스가 만들어지고 동일하게 수행 된 다음 세 번째 자식 프로세스 인 자식 프로세스가 만들어집니다. 이 세 명의 자식이 값을 수정하고 실행을 완료하면 부모 프로세스가 공유 메모리를 해제 한 다음 프로그램을 종료합니다. 나는이 "shmctl"블록이 원하는 효과를 얻는다는 인상을 받고 있었지만 그렇게 보이지는 않았다.공유 메모리 해제

if ((shmctl (shmid, IPC_RMID, (struct shmid_ds *) 0)) == -1) 
{ 
    perror ("shmctl"); 
exit (-1); 
} 

이 블록을 따라하기 때문에 이전에 같은 값을 인쇄하는 동안 다음과 같은 결과가 나옵니다. 이것은 포인터가 여전히 동일한 비트의 메모리에 액세스하고 있음을 나타내지 않습니까, 아니면 제가 잘못 생각합니까?

입력 해 주셔서 감사합니다. 설명 shmctl 남자 페이지에서

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

/* change the key number */ 
#define SHMKEY ((key_t) 5600) //7890 

typedef struct 
{ 
    int value; 
} shared_mem; 

shared_mem *total; 

/*----------------------------------------------------------------------* 
* This function increases the value of shared variable "total" 
* by one all the way to 100000 
*----------------------------------------------------------------------*/ 

void process1() 
{ 
    int k = 0; 

    while (k < 100000) 
    { 
     k++; 
     total->value = total->value + 1; 
    } 
    printf ("From process1 total = %d\n", total->value); //process 1 prints out total and returns to main() function 
} 

/*----------------------------------------------------------------------* 
* This function increases the vlaue of shared memory variable "total" 
* by one all the way to 170000 
*----------------------------------------------------------------------*/ 

void process2() 
{ 
    int k = 0; 

    while (k < 170000) 
    { 
    k++; 
    total->value = total->value + 1; 
    } 
    printf ("From process2 total = %d\n", total->value); //process 2 prints out total and returns to main() function 
} 
/*----------------------------------------------------------------------* 
* This function increases the vlaue of shared memory variable "total" 
* by one all the way to 200000 
*----------------------------------------------------------------------*/ 

void process3() 
{ 
    int k = 0; 

    while (k < 200000) 
    { 
    k++; 
    total->value = total->value + 1; 
    } 
    printf ("From process3 total = %d\n", total->value); //process 3 prints out total and returns to main() function 
} 

/*----------------------------------------------------------------------* 
* MAIN() 
*----------------------------------------------------------------------*/ 

int main() 
{ 
    int shmid; 
    int pid1; 
    int pid2; 
    int pid3; 
    int ID; 
    int status; 

    char *shmadd; 
    shmadd = (char *) 0; 

/* Create and connect to a shared memory segmentt*/ 

if ((shmid = shmget (SHMKEY, sizeof(int), IPC_CREAT | 0666)) < 0) 
{ 
    perror ("shmget"); 
    exit (1); 
} 


if ((total = (shared_mem *) shmat (shmid, shmadd, 0)) == (shared_mem *) -1) 
{ 
    perror ("shmat"); 
    exit (0); 
} 

total->value = 0; 

if ((pid1 = fork()) == 0) //first child created 
{ 
    process1(); //first child process begins 
} 

while((ID = wait(&status)) != -1) //parent loops until 1st child is finished 
printf("child %d is finished\n", ID); //parent prints out returned value after child is finished 


if ((pid1 != 0) && ((pid2 = fork()) == 0)) //second child created 
{ 
    process2(); //second child process begins 
} 

while((ID = wait(&status)) != -1) //parent loops until 2nd child is finished 
printf("child %d is finished\n", ID); //parent prints out returned value after child is finished 

if ((pid1 != 0) && (pid2 != 0) && ((pid3 = fork()) == 0)) //third child created 
{ 
    process3(); //third child process begins 
} 

while((ID = wait(&status)) != -1) //parent loops until 3rd child is finished 
printf("child %d is finished\n", ID); //parent prints out returned value after child is finished 



if ((pid1 != 0) && (pid2 != 0) && (pid3 != 0)) 
{ 
    if ((shmctl (shmid, IPC_RMID, (struct shmid_ds *) 0)) == -1) 
    { 
perror ("shmctl"); 
exit (-1); 
    } 

    printf ("\t\t End of Program.\n"); //prints after all children have finished 

    printf("value after memory release:%d\n", total->value); 
} 
return 0; 
} 

/***** Note: loop for parent to wait for child processes to finish and print ID of each child*****/ 
+0

이것은 C++로 태그 지정 되나요? C가 더 관련성이 있었습니까? –

+0

실례합니다. 그것을 잡아 주셔서 감사합니다. – NicholasNickleby

답변

2

:

IPC_RMID

마크 세그먼트 파괴한다. 세그먼트는 실제로 마지막 프로세스가 분리 한 후에 (즉, 연관된 구조체 shmid_ds의 shm_nattch 멤버가 0 일 때) 파괴 된 일뿐입니다. 발신자는 소유자 또는 작성자이거나 권한이 있어야합니다. 세그먼트 이 삭제 대상으로 표시되면 IPC_STAT에 의해 으로 검색된 연관된 데이터 구조의 shm_perm.mode 필드의 (비표준) SHM_DEST 플래그 이 설정됩니다.

발신자는 세그먼트가 결국 소멸되도록해야합니다. 그렇지 않으면 폴트 된 페이지가 메모리에 남아 있거나 스왑이됩니다.

즉 코드가 세그먼트를 파괴로 표시하지만 프로그램이 종료 될 때까지 코드를 분리하지 않습니다.

이전에 분리하려는 경우 shmdt(total);으로 전화 할 수 있습니다. 마지막 printf 전에이 작업을 수행하면 printf가 seg 오류를 일으킬 수 있습니다.

+0

우수. 설명 주셔서 대단히 감사합니다! – NicholasNickleby