2013-06-10 1 views
0
class test_class 
    { 
     public: 
     std::string str; 
     int ival; 
    }; 

    int main() 
    { 
     int shmkey = 3450; 
     int shmid; 

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

     test_class **test_obj; 
     if((test_obj = (test_class**) shmat(shmid, NULL, 0)) == (test_class**) -1) 
     { 
      perror("shmat"); 
      exit(1); 
     } 

     test_class* new_obj = new test_class(); 
     *test_obj = new_obj; 

     (*test_obj)->str = "parent process string"; 
     (*test_obj)->ival = 9; 

     pid_t pid = fork(); 

     if(pid == 0) 
     { 
      int shmkey = 3450; 
      int shmid; 

      if((shmid = shmget(shmkey, sizeof(test_class*), 0666)) < 0) 
      { 
       perror("shmget"); 
       exit(1); 
      } 

      test_class **test_obj; 
      if((test_obj = (test_class**) shmat(shmid, NULL, 0)) == (test_class**) -1) 
      { 
       perror("shmat"); 
       exit(1); 
      } 

      (*test_obj)->str = "child process string"; 
      (*test_obj)->ival = 10; 

      exit(EXIT_SUCCESS); 
     } 

     sleep(3); 
     std::cout << (*test_obj)->str << std::endl; 
     std::cout << (*test_obj)->ival << std::endl; 

     shmctl(shmid, IPC_RMID, 0); 

     return 0; 
    } 


This code output is :- 
child process string 
9 

이 프로그램에서는 자식 프로세스에서 공유 메모리 개체 (힙 메모리)를 업데이트하고 부모에서 업데이트 된 값을 인쇄합니다. 출력에서 볼 수 있듯이 문자열은 올바르게 업데이트하지만 int는 업데이트하지 않습니다. 힙 메모리에 있기 때문에 업데이트하지 않아야합니다. 여기에서 문자열이 어떻게 업데이트됩니까?shmget shmat가 제대로 작동하지 않습니다.

어떤 도움이 필요합니까?

1) 부모 프로세스가 개체의 수정을 완료하기 위해 자식 프로세스를 기다리지 않는다, 그래서 무엇을 출력 것이라고 예측할 수있다 :

덕분에, Gaurav

답변

2

코드는 몇 가지 문제가 있습니다. 값을 출력하기 전에 wait(NULL)을 부모 프로세스에 넣습니다.

2) 자식 프로세스는 std::string을 변경하고 실제로는 string 개체 내의 일부 포인터를 변경하지만 자식과 부모는 서로 다른 힙과 주소 공간을 가지므로 매우 위험합니다. 대신 char 배열을 공유 메모리에 저장해야합니다.

3) 상기 공유 메모리에 이미 fork 부모 프로세스 얻어진 중복으로 자식 프로세스 shmget & shmat을 수행 할 필요가 없다;

4) test_class의 필드를 volatile으로 지정하여 컴파일러가 값을 읽는 것을 최적화하지 않도록해야합니다.

+0

5)은 '* = test_obj 새로운 test_class()와 공유 메모리 블록의 비 - 공유 메모리에 대한 포인터를 저장하고,'. 이것은 예제 프로그램에서 작동하지만, 전체 주소 공간이'fork()'에서 자식 프로세스로 효과적으로 복사되기 때문에 가능합니다. – Casey

+0

그래, 고마워, 나는 그것을 간과했다 - 나는 그가 포인터가 아니라 객체를 저장했다고 생각했다. – Inspired

+0

개체를 저장하는 경우이 문제가 발생했다고 생각하지 않습니다. 어쨌든, 내 요점은, 힙 메모리에있는 것처럼 자식 프로세스에서 문자열이 어떻게 업데이트 되는가입니다. – Gaurav

관련 문제