멋진 삶을 꿈꾸며 :: 공유메모리를 이용한 채팅방의 원리

shared memory를 이용한 IPC 예제(출처 : PHP 스쿨)

대형통신망에 가면 서로 통신을 하면서 채팅,쪽지를 보내곤하죠.
단순히 상대방에게 메세지를 보내면될거 가지고 뭐그리 어려울게 있냐고들 하시더군요.
그래서 제가 이렇게 나서서 간단한 강좌를 하나 만듭니다. 꼬옥 보시길

유닉스에서 프로그램이 실행되면서 프로세스 하나가 생성되겠죠.
어떤 사람은 vi 에디터를 사용하고 어떤 사람은 telnet 을 이용해 통신을 하고..
그들은 모두 독립된 메모리 영역을 사용하고 있으며 절대 중복된 메모리 공간을
사용하지 않습니다. 만약 중복되게 사용되면 충돌이나기 때문이죠.

하지만 만약 서로 메모리를 중복되게 사용하면서 충돌도 안난다면 그 사이의
통신은 같은 메모리상에서 이루어지기때문에 상당히 빠르겠죠?
이것을 잘 이용하면 채팅방도 무지 빠르게 작동할 수 있도록 만들 수도 있답니다.

실제로 이런 방법을 모르던 옛날 시절에는 디바이스에 직접 echo 명령을 사용하여
메세지를 보내는 방식을 사용한 적도 있었답니다.(쉘 프로그래밍을 이용한 bbs)

어짜피 더이상 설명해봐야 소귀에 경읽기가 될 수 있으므로 직접 실전으로
들어가서 간단한 소스를 보여드릴께요.

Click Read the full post
(Language : c)
  1. #include
  2.  
  3. #define SIZE 300
  4. #define MODE 0666
  5.  
  6. int
  7. main(int argc, char **argv)
  8. {
  9.         struct shmid_ds ss;
  10.         int shmid;
  11.         char buf[50], *shmaddr;
  12.         key_t key;
  13.        
  14.         /* 공유 메모리를 사용하기위해 여는 작업입니다. */
  15.         if ( (shmid = shmget (key, SIZE, IPC_CREAT | MODE) ) == -1 ) {
  16.                 printf("공유 메모리를 열수 없습니다.");
  17.                 exit(1);
  18.         }
  19.        
  20.         printf("공유메모리 세그먼트 지시자 : %d",shmid);
  21.        
  22.         if ( fork() != 0) { /* 부모 프로세스 */
  23.                 /* 공유메모리 세그먼트 지시자(shmid) 를 참조하여 shmaddr에 넣는다. */
  24.                 shmaddr = shmat(shmid, NULL,MODE);
  25.                 strcpy(shmaddr,argv[1]);
  26.                 /* 공유 메모리에 데이터(shmaddr)를 집어넣는다. */
  27.                 shmdt(shmaddr);
  28.         }
  29.         else { /* 자식 프로세스 */
  30.                 /* 공유메모리 세그먼트 지시자(shmid) 를 참조하여 shmaddr에 넣는다. */
  31.                 shmaddr = shmat(shmid, NULL, MODE);
  32.                 strcpy(buf,shmaddr);
  33.                 printf("%s ",buf);
  34.         }
  35. }

자. 이해가 가셨는지요?

위의 프로그램이 단순히 하는 일은 이렇습니다.
shmget() 함수를 이용하여 공유메모리를 열고,
shmat()를 이용하여 공유메모리의 선택부분을 가져오고,
shmdt()를 이용하여 공유메모리에 자료를 넣습니다.

주의할 점은 shmget() 함수를 사용하여 지시자를 받은곳만 접근이 가능합니다.
key=shmget(); 부분에서 key가 1인데 shmat()에서 key 값을 2로 해서 가져오려하면
에러가 납니다. 지정된 메모리만 접근이 가능하기때문이죠. 알고 보면 쉽죠?

자 그럼 이것을 이용하여 서로 다른 프로세스에서 어떻게 자료를
공유하는지 알아보죠. 프로그램을 몇가지 만들것입니다.

1. 공유메모리 영역 열기
2. 공유메모리의 선택부분에 데이터를 쓰기
3. 공유메모리의 선택부분에서 데이터를 읽기


이렇게 세가지의 프로그램을 만들것입니다.
마음을 단단히 먹지 않으셔도 되요.
위에 소개된 세가지 이상의 함수는 사용하지 않습니다.


1. 공유메모리 영역 열기 (Language : c)
  1. #include
  2. #include
  3.  
  4. #define SIZE 300
  5. #define MODE 0444
  6.  
  7. int main(int argc, char **argv)
  8. {
  9.         struct shmid_ds ss;
  10.         int shmid;
  11.         char buf[50],*shmaddr;
  12.         key_t key=0;
  13.        
  14.         if ( (shmid = shmget (key, SIZE, IPC_CREAT | MODE) ) == -1 ) {
  15.                 printf("실패");
  16.                 exit(1);
  17.         }
  18.        
  19.         printf("shmid value : %d",shmid);
  20. }  

단순히 shmget() 함수를 사용하여 공유메모리 각 세그먼트의 지시자(shmid)만
생성되게 하였습니다.
참고로 key값을 0으로 하면 언제나 새로운 공유메모리를 할당합니다.
단순히 컴파일해서 실행하면 이렇습니다. (실행파일 : sm_make )
$ ./sm_make
shmid value : 1
$ ./sm_make
shmid value : 2
$ ./sm_make
shmid value : 3
$ ./sm_make
shmid value : 4
...
...
이렇게 하나씩 계속 늘어납니다. 저 1,2,3,4... 숫자들이 지시자입니다.


2. 공유메모리의 선택부분에 데이터를 쓰기 (Language : c)
  1. #include
  2.  
  3. #define MODE 0666
  4.  
  5. int main(int argc, char **argv)
  6. {
  7.         int shmid;
  8.         char *shmaddr;
  9.        
  10.         shmid = atoi(argv[1]);
  11.         shmaddr = shmat(shmid, NULL, MODE);
  12.         sprintf(shmaddr,argv[2]);
  13.         shmdt(shmaddr);
  14. }

여기까지입니다.
금방 눈치챘죠? 단순히 아규먼트 두개를 받아서 첫번째는 key값 그 다음은 data 값을
넣는 프로그램입니다.
실행하면 이렇게 됩니다. (실행파일 : sm_add )
$ ./sm_add 1 loveyou ( 1번 지시자에 loveyou 라는 문자열을 저장 )
$ ./sm_add 2 hohoho ( 2번 지시자에 hohoho 라는 문자열을 저장 )

자 이제 마지막 프로그램


3. 공유메모리의 선택부분에서 데이터를 읽기 (Language : c)
  1. include
  2.  
  3. #define MODE 0666
  4.  
  5. int main(int argc, char **argv)
  6. {
  7.         int shmid;
  8.         char *shmaddr;
  9.        
  10.         shmid = atoi(argv[1]);
  11.         shmaddr = shmat(shmid, NULL, MODE);
  12.        
  13.         printf("key : %d data : %s",shmid,shmaddr);
  14.  
  15. }

설명이 필요없을줄 압니다.
실행하면 다음과 같습니다. ( 실행파일 : sm_read )
$ ./sm_read 1
key : 1 data : loveyou
$ ./sm_read 2
key : 2 data : hohoho
이렇게 되죠..
언제 시간나면 좀더 깊게 알려드릴께요.
기초가 중요하기때문에 이것을 바탕으로 한번 다른 종류의 프로그램을 만들어보세요.

출처: http://virtual140.emde.inha.ac.kr/khdpmain/read.php3?table=tech&no=101&page=1
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기
Posted by 소리나는연탄.
TAGS , ,

Trackback URL : http://wowfriend.net/trackback/45


Leave your greetings here.

  1. Comment RSS : http://wowfriend.net/rss/comment/45
  2. 비밀방문자 2010/03/20 23:57  Modify/Delete  Reply  Address

    관리자만 볼 수 있는 댓글입니다.

  
  
  
  
  
  
  
  
 
« Previous : 1 : ... 103 : 104 : 105 : 106 : 107 : 108 : 109 : 110 : 111 : ... 161 : Next »