공유메모리 관련한 의문들..(이거진짜 웃기는 놈이네요.. ㅡㅡ;;
글쓴이: jongsuknim / 작성시간: 월, 2004/08/09 - 11:48오전
같은 shmid 로 shmat 할때마다 다른 주소가 리턴되는데요..
거기를 참조하면 다른 주소라도 같은 곳을 변경한것처럼 변경되네요..
반대로
위와는 다른 shmid로 shmat 하면 위와 같은 식의 주소가 리턴되고
거기를 참조하면 위와는 다른 곳을 참조하네요..
결국 shmid 로 메모리의 위치가 변경된다는 말 같은데..
하지만 내가 쓰는곳은 메모리 주소인데 어떻게 이런것들이 가능한지요..
임의로 그 주소값을 참조하려면 세그먼트 에러가 나네요..
제가 실험한 첨부파일도 추가 합니다..
아참.. ourhdr.h 는 sys/types.h sys/ipc.h sys/shm.h 로 변경해 주세요~~~
File attachments:
첨부 | 파일 크기 |
---|---|
![]() | 754바이트 |
Forums:
가상메모리의 의미를 다시 새겨보시기 바랍니다.
shmat로 받는 주소는 가상메모리 주소일 뿐입니다.
당연히 어떤 주소가 받던지 가리키는 곳은 동일하므로 공유메모리에 접근하는 것입니다. 가상메모리 주소는 절대적인 값이 아닙니다. 다른 프로세스가 같은 주소를 보고 있다고 해도 그 실제적인 물리적 메모리 주소는 다릅니다.
페이지테이블에서 해석되어 실제 접근하는 물리적 주소값과 혼동하시는것 같네요.
========================================
* The truth will set you free.
한 프로세스에서 메모리 주소는 실제 메모리의 물리적인 주소가 아닌 하드웨
한 프로세스에서 메모리 주소는 실제 메모리의 물리적인 주소가 아닌 하드웨어적으로 변경된 논리적인 주소입니다.
즉, 특정 메모리를 일반 프로그램에서 접근하려 하면 그 논리주소를 실시간으로 물리주소로 변경한후 그 곳의 내용을 읽어서 넘겨주지요.
이렇게 하기 때문에 하나의 물리적인 메모리를 수 많은 프로세스가 사용해도 단편화되지 않은 일련의 큰 메모리 주소를 얻을 수 있게되는거죠.
다른 시퓨에선 뭐라고 하는지 모르겠지만 인텔 시퓨에서는 메모리 접근법에는 real 모드와 protect 모드가 있는데요.
sunyzero 님께서 생각하시는 그런건 real 모드일때의 이야기이고 실제 요즘 커널들은 모두 protect 모드를 이용합니다.
real 모드로 유명한 OS는 ms-dos 겠죠? ^^
공유메모리는 protect 모드의 특성을 이용해서 물리적인 고정 메모리 주소를 프로세스에게 임의의 논리적인로 맵핑을 한후에
그 주소를 반환해 주기 때문에 일반 프로그램 개발자는 그 논리적인 주소만을 사용하게 되지요.
그래서 shmat 에 보면 내가 특정 주소로 맵핑해달라고 요청하는 인자가 있긴하지만,
man 페이지에 나온 설명대로 요청한 주소값을 항상 반환해 주는건 아니지요.
이런 사실을 몰랐을 때
공유메모리에 내에 공유메모리내의 특정 주소를 가르키는 포인터를 기록하고
다른 프로세스에서 그 포인터를 이용해서 공유메모리의 특정 위치를 접근하도록 코딩했다가 낭패를 본적이 있었지요.
이걸 shmat 으로 부터 얻은 공유메모리 시작 주소로부터 항상 상대적인 위치를 계산해서 접근하는 방식으로 변경을 했지요.
이와 관련된 이론은 OS 서적 에서 다루고 있습니다.
답변감사합니다.
지금까지 잘못생각하고 있었네요.. 가상 메모리라...
그러니깐 프로세스마다 따로 가상메모리 주소가 존재한다는 말이군요..
다시말하면 가상메모리와 실제메모리와의 매핑주소를 프로세스마다 가지고 있다는 말이죠?
그래서 다른 프로세스에서 같은 가상메모리 주소를 사용할수 있고..
shmat 할때는 그럼 같은 물리 주소를 다른 논리 주소로 리턴하는 거겠네요..
이런 식으로하면 다른 프로세스에서 같은 물리 주소를 접근할수없겠네요..
그래서 공유메모리라는게 있고...(지금까지는 다른 프로세스라도 같은 포인터 주소로 접근이 가능한줄 알았습니다..)
제가 말한것은 리얼모드가 아닙니다. 리얼모드와 보호모드의 차
제가 말한건 real모드가 아닌 보호모드입니다. 제가 말한 가상메모리는 보호모드(protected mode)의 메모리구조를 의미합니다. 그 자체가 보호모드의 구현이죠.
OS개론이나 특론을 배우면 더 확실하게 아실테지만, 이건 CPU에 국한된게 아닙니다. 윗분이 알고 계신 인텔CPU에서 말하는게 아니라 이건 운영체제개념에 관련된것입니다. 다른 유닉스도 다 보호모드에서 작동합니다. 보호모드가 되지 않는다면 메모리관리측면에서 큰 문제(충돌이나 할당등...)를 야기할 수 있겠죠. 따라서 가상메모리자체도 사용할 수 없겠죠.
실제로 가상메모리 자체에는 스와핑이나 캐시관리, 페이지관리등의 많은 기술이 들어가게 됩니다. 이것이 있기 때문에 물리적인 메모리보다 더 큰 메모리를 사용할 수 있게 되죠.
옛날에 도스를 사용하던 시절에는 리얼모드라고 해서 주소를 절대적인 번지로 접근하는 방법을 사용했습니다. 따라서 메모리 관리에서 침범이 일어나면 바로 OS가 죽어버리는 일이 생겼죠. 그리고 멀티프로세싱은 당연히 불가능할수밖에 없었죠.(구현자체가 힘들죠) 아마도 윗분은 이것을 보고 리얼모드가 도스모드를 말하는것이라고 생각하시는것 같습니다. 가상메모리가 등장한뒤에는 이제 이런 것을 생각하는것 자체가 아주먼 이야기가 되어버린것도 있죠.
========================================
* The truth will set you free.
아 죄송합니다.[quote="devilhero"]sunyzero
아 죄송합니다.
에서 sunyzero 님이 아니고 jongsuknim 님인데 제가 잘못 적었네요.
죄송합니다.
음.. 그렇다면..
예전에 도스시절에 즐겨 했던 게임 위자드 같은건 유닉스에서 만들수 없다는 말이 되나요?
게임위저드는 메모리를 직접 참조했던 걸로 기억하는데..
네 게임 위저드 같은건 만들 수가 없는 것으로 알고 있습니다.그래
네 게임 위저드 같은건 만들 수가 없는 것으로 알고 있습니다.
그래서 윈98 까지는 그런게 있었는데 NT 계열에서는 그런 프로그램이 존재하지 않는거죠.
하지만 잠깐 생각해 보면, 타 프로세스의 특정 메모리주소에 있는 값을 읽어 오는 시스템콜 같은게 있다면 쉽게 구현이 가능할 것 같은데 보안상이나 안정성 문제로 그런걸 커널에서 제공하지 않을 듯 하군요.
혹시 이런게 존재하나요?
음.... 윈도XP에서 돌아가는 게임 위자드 같은게 있는데...실
음.... 윈도XP에서 돌아가는 게임 위자드 같은게 있는데...
실행시키고 나서 원하는 응용 프로그램을 선택한 후에 사용할 수 있더군요.
공유 메모리 프로그램 유의 사항.
shmidr = shmget((key_t)1234,sizeof(struct sh_f),0666|IPC_CREAT);
이렇게 정의 할때 1234 는 서로 다른 프로그램에서 공통으로 지정해 주어야 합니다. 그래야 같은 어드레스를 참조해서 메모리 공유가 가능합니다.
그렇지 않으면 서로 다른 메모리를 참조하게 되지요.
그리고 sh_f로 정의된 공유메모리 부분의 struct는 같아야 합니다.
그렇지 않으면 읽어올때 이상한 데이터가 읽혀오게 됩니다.
.....
리눅스 네트웍 개발 (FA) /유비쿼터스 네트웍 하드웨어 개발 프로젝트 진행/인터넷을 통한 원격제어/
리눅스 베이스 FA 구현/초소형 무선랜 모듈개발 진행중/리눅스 웹 통합시스템 구축
댓글 달기