복잡한 프로그래밍 환경에서 다수의 프로세스들은 서로 협력하기 위하여 서로 통신하고 자원과 정보를 공유를 한다. 커널에서는 이것이 가능한 방법을 제공하는데, 이를 프로세스간 통신(Inter-process Communication) 또는 IPC라 부른다. 프로세스간 통신을 하는 목적은 데이터전송, 데이터 공유, 사건 전송, 자원 공유, 프로세스 제어를 하기 위함이다. 이를 위하여 전통적인 UNIX에서는 시그널(signal), 파이프(pipe), 프로세스 추적(process tracing)을 기능을 사용하였다. 그러나, 많은 사용자 프로그램들에서는 이것만으로 IPC를 충족할 수 가 없었으며, 이것은 System V 릴리즈 버전에서 메시지 큐, 세마포어, 공유 메모리 기법을 사용하게 되었다.
[1] 메세지 큐(Message Queue) system V message Queue는 커널에서 생성 되어지는 큐에 의하여 메시지를 서로 교환하는 것이 가능하도록 메시지 전달 인터페이스를 제공한다. 인터페이스는 Solaris 환경에서 enqueue, dequeue 메시지로 제공되어진다. enqueue하는 것은 큐의 끝에 메시지를 두는 것이며, dequeue는 큐 또는 처음 메시지로부터 기술한 첫 번째 메시지를 제거한다. Solaris 8에서는 msgsys:msginfo_msgssz, msgsys:msginfo_msgmap, msgsys_msginfo_msgseg 파라메터를 더 이상 사용하지 않으며, 다음 설명에서도 이들에 대해서도 설명하지 않는다.
특별한 설정을 하지 않으면 기본 값으로 설정이 되지만, 이것은 프로그램들이 시스템 요청을 하는데 메시지의 전송과 수신에 성능 상의 느린 결과를 나타낼 수 있다. 다음은 Solaris 8에서 제공하는 메시지 큐 관련 파라메터이다.
파라메터 |
내 용 |
msgsys:msginfo_msgmax |
기본값은 2048byte이며, 최대 물리적인 메모리의 크기만큼 설정 할 수 있다.(단위 byte) 이 파라메터는 메시지의 최대 크기를 지정하며, 만약 메시지가 주어진 값보다 길다면 EINVAL 에러를 리턴한다. 보통 제공하는 소프트웨어 밴더(vendor)에서 그 크기를 제시를 한다. |
msgsys:msginfo_msgmnb |
기본값은 4096byte이며, 최대 물리적인 메모리의 크기만큼 설정 할 수 있다.(단위 byte) 이것은 하나의 메세지 큐가 수용할 수 있는 메세지의 최대 크기를 제한하며, 이 값은 메세지 큐에 보관되어 있는 메세지들의 크기(byte)의 합이라 할 수 있다. 만약, 메시지가 큐의 길이보다 더 크다면 메시지를 보내는 msgsnd는 블록 공간(block space)가 사용 가능할 때까지 또는 non-blocking모드로 기술되면 EAGAIN을 리턴한다. 논리적으로 magmnb가 msgmax보다 커야 한다. msgmax와 마찬가지로 소프트웨어 벤더에서 제시를 한다. |
msgsys:msginfo_msgmni |
기본값은 50이며, 최대 MAXIN 까지 이다. 이것은 시스템에서 가용 가능한 메세지 큐 확인자(identifier)의 수를 정의한다. 즉, 각각의 메시지 큐는 하나의 ID를 요구를 하는데, 이를 구분하기 위한 수를 의미한다. 시스템은 msgmni에 주어진 수만큼 미리 할당하며, 하나의 ID 구조의 크기는 144byte이다. 만약 msgget이 사용할 수 없는 ID라면 ENOSPC 에러를 리턴한다. |
msgsys:msginfo_msgtql |
기본값은 40이며, 최대 MAXINT이다. 시스템에서 사용 가능한 메시지 z의 헤더(header) 수를 정의한다. 메세지 큐에 들어 있지만 아직 읽혀지지 않은 메세지는 하나의 메세지 큐 헤더를 차지한다. 시스템은 이 값만큼의 msgtql 제어 구조에 해당되는 커널 메모리를 미리 할당한다. 하나의 제어 구조는 12 바이트이다. 만약, msgsnd는 블록(block) 또는 사용할 수 있는 것이 없다면 EAGAIN을 리턴하고, 블럭킹 옵션(blocking option)으로 기술한 것에 의존한다. |
파라메터를 보면 :앞 부분에 있는 것이 메세지 큐에 대한 모듈이며, : 다음에 있는 것이 실제적인 파라메터이다.
메시지 큐 파라메터를 시스템에 적용하기 위해서는 /etc/system 파일에 다음과 같이 정의해야 한다.
set msgsys:msginfo_variable = value
variable는 각각 msgmax, msgmnb, msgmni, msgtql이 될 수 있으며, value에는 variable에 따른 값을 주며 된다. 다음은 메시지 큐에 대하여 /etc/system 파일에 설정한 예이다.
set msgsys:msginfo_msgmax = 131070 set msgsys:msginfo_msgmnb = 131070 set msgsys:msginfo_msgmni = 256 set msgsys:msginfo_msgtql = 800 forceload: sys/msgsys
이들 내용이 적용되어 지기 위해서는 /etc/system 파일에 추가 또는 변경을 한 후 시스템을 리부팅 해야 한다. 다음에 설명하는 세마포어, 공유 메모리 관련 파라메터들도 적용 되어지기 위해서는 시스템의 리부팅이 필요하다. 그리고, 메시지 큐 모듈이 로드(load) 되어지도록 "forceload: sys/msgsys"를 추가해야 한다. 시스템이 리부팅이 된 다음에 이들의 크기를 확인하려면 sysdef를 사용하여 확인 할 수 있다. # sysdef -i : * * IPC Messages * 131070 max message size (MSGMAX) 131070 max bytes on queue (MSGMNB) 256 message queue identifiers (MSGMNI) 800 system message headers (MSGTQL) * :
그리고, 메시지 큐에 대한 모듈(module)이 정상적으로 로드(load) 되었는지의 확인은 modinfo를 사용하여 확인 할 수 있다.
# modinfo | grep msgsys 35 1027e826 1eb8 49 1 msgsys (System V message facility) 35 1027e826 1eb8 49 1 msgsys (32-bit System V message facilit)
Solaris 2.5 이후의 버전에서는 메시지 큐의 구조가 커널 메모리의 1/4(25%) 이상을 사용하는 것으로부터 보호가 되며, 이 제한 값보다 크게 주어진다면 "msgsys: can't load module, too much memory requested"라는 경고 메시지가 출력이 되며, 모듈은 로드 되지 않는다.
[2] 세마포어(Semaphore)
세마포어는 프로세스간의 동기화를 하는데 주요한 기능을 제공한다. 주로 동기화 연산이 필요한 경우 매우 중요한 역할을 한다. 세마포어[Dijk 65]는 두 개의 기본적인 연산인 P()와 V()의 정수 값을 가지는 객체라 할 수 있다. P()연산은 세마포어의 값을 하나 줄이고, 새 값이 0보다 작으면 봉쇄 시키고, V() 연산은 값을 증가시키는데, 결과 값이 0보다 크거나 같아지면, V() 연산은 기다리고 있던 쓰레드나 프로세스를 깨우게 된다. 그리고, UNIX 시스템 자체적으로 커널이 자신에 대하여 동기화를 하기 위해서도 세마포어를 사용한다. 다음은 Solaris 8에서 제공하는 세마포어 관련 파라메터이다.
파라메터 |
내 용 |
semsys:seminfo_semmni |
기본값 10, 최대 65535로서, 세마포어 확인자(Identifiers)의 최대 수를 정의한다. 각각 설정된 세마포어에 대하여 84 byte의 커널 메모리가 미리 할당된다. |
semsys:seminfo_semmns |
기본값 60, 최대 MAXINT로서, 시스템에 있는 세마포어의 최대 수를 정의한다. 하나의 세마포어는 16byte의 커널 메모리가 할당된다. |
semsys:seminfo_semvmx |
기본값 32767, 최대 65535, 세마포어의 최대값의 설정한다. "undo"구조와 semaem과의 관계로 인하여 32767보다 크게 지정을 해야 한다. 보통 기본값으로는 충분하지 못하기 때문에 소프트웨어 환경에 따른 적정한 값을 설정한다. |
semsys:seminfo_semmsl |
기본값 25, 최대 MAXINT, 하나의 세마포어 ID에 있는 세마포어 최대 수를 설정한다. 이 파라메터의 값은 semmns와 같거나 적어야 한다 .만약, 이 값을 너무 크게 설정을 한다면 몇 개의 세마포어 ID가 시스템 전체에 있는 세마포어를 독식 할 수 있다. |
semsys:seminfo_semopm |
기본값 10, 최대 MAXINT, 하나의 세마포어 요청에 의하여 처리할 수 있는 운영(operation)의 수를 제한한다. |
semsys:seminfo_semmnu |
기본값 30, 최대 MAXINT, 시스템이 있는 "undo" 구조를 정의한다. 하나의 프로세스에 대하여 "undo" 기록하기 위하여 하나의 undo 구조가 필요하다. |
semsys:seminfo_semume |
기본값 10, 최대 MAINT, 하나의 프로세스에 의하여 사용되어지는 세마포어 "undo" 최대 수를 설정한다. |
semsys:seminfo_semaem |
기본값 16384, 최대 65535, exit시 보정될 최대 값을 제한한다. |
세마포어 관련 파라메터의 설정에 있어서도 메시지 큐와 같다. 단지 사용하는 모듈(module)과 그 속성을 설정하는 변수(variable)이 다르다. /etc/system 파일에 다음의 형식으로 정의한다.
set semsys:seminfo_variable = value
다음은 /etc/system 파일에서 세마포어 관련 파라메터의 설정 예이며, 설정한 파라메터가 적용되어지기 위해서는 시스템의 리부팅을 해야만 한다.
set semsys:seminfo_semmni = 256 set semsys:seminfo_semmap = 258 set semsys:seminfo_semmns = 1024 set semsys:seminfo_semmnu = 1024
현재 설정되어 있는 것을 확인 하기 위해서는 sysdef를 사용한다.
# sysdef : * IPC Semaphores * 256 semaphore identifiers (SEMMNI) 1024 semaphores in system (SEMMNS) 1024 undo structures in system (SEMMNU) 25 max semaphores per id (SEMMSL) 10 max operations per semop call (SEMOPM) 10 max undo entries per process (SEMUME) 32767 semaphore maximum value (SEMVMX) 16384 adjust on exit max value (SEMAEM) *
이 세마포어에 대한 모듈이 정상적으로 로드 되어 있는지는 "modinfo"로 확인 할 수 있다.
# modinfo | grep semsys 32 1027988e 2870 53 1 semsys (System V semaphore facility) 32 1027988e 2870 53 1 semsys (32-bit System V semaphore facil)
[3] 공유 메모리(shared memory)
공유 메모리(shared memory)는 물리적인 메모리의 특정 영역에 대하여 프로세스들에 의해 공유되어지는 영역(region)이라 할 수 있다. 프로세스들은 이 공유 메모리 지역을 자신의 가상 메모리 영역에 부착(attach)하여 사용한다. 영역은 데이터 읽기/쓰기의 시스템 호출을 사용하지 않고 다른 방법을 접근을 하기 때문에 프로세스간 데이터를 공유하는 기법 중 가장 빠르다 할 수 있다. 예를 들어, 하나의 프로세스가 공유 메모리의 영역에 기록(write)를 하게 된다면, 이 내용은 이 영역을 공유하는 모든 프로세스들에 의해 바로 보여지게 되어 아주 빠르게 데이터를 고유하게 된다.
공유 메모리의 구현에 있어서는 시스템의 가상 메모리(Virtual memory) 구조에 크게 의존하며, 데이터의 복사나 시스템 요청을 사용하지 않고 많은 양의 데이터를 공유하는 매우 빠르고 융통성 있는 기법을 제공한다. 그러나, 이 기법의 동기화 기법을 제공하지 않는다는 단점이 있다. 예를 들면, 두 개의 프로세스가 같은 공유 메모리 영역의 내용을 변경하려고 할 경우, 커널은 이를 순차적으로 처리를 해야 하나, 그렇게 하지 않으며, 쓰여진 데이터는 엉키게 된다. 그래서, 공유 메모리를 사용하는 프로세스들은 프로세스들 간에 동기화를 하는 프로토콜을 고안해야 하며, 이것은 공유 메모리 성능에 영향을 주는 요소로 작용할 수 있다. 다음은 Solaris 8에서 제공하고 있는 공유 메모리 관련 파라메터이다.
파라메터 |
내 용 |
shmsys:shminfo_semmax |
기본값 1M, 공유 메모리 세그멘트의 최대 크기로서, 커널은 이 값 만큼의 메모리를 미리 할당하여 별도로 관리하는 것이 아니고 필요할 때마다 할당 받아 사용한다. 그래서 이 파라메터의 값을 크게 주어도 시스템에는 나쁜 영향을 주지 않는다. 최대 값은 32bit 커널의 경우 MAXINT, 64bit 커널의 경우 MAXINT64까지 설정 할 수 있다. |
shmsys:shminfo_semmin |
기본값 1byte, 공유 메모리 세그멘트의 최소 크기로서 변경을 할 필요가 없다. 이 파라메터의 설정 범위는 0 ~ 물리적 메모리까지 이다. |
shmsys:seminfo_semmni |
기본 값 100byte, 최대 MAXINT, 시스템에서 생성되어 지는 공유 메모리 세그멘트의 수를 제한을 한다. |
shmsys:seminfo_semseg |
기본값은 6byte, 최대 32767, 하나의 프로세스에 할당 될 수 있는 공유 메모리의 세그멘트 수를 제한한다. |
이들 파라메터는 /etc/system 파일에 다음 형식으로 설정한다.
set shmsys:shminfo_variable = value
다음은 /etc/system 파일에 공유 메모리 적용의 예를 보여주고 있다. 설정 후 시스템에 적용하기 위해서는 시스템을 리부팅 해야 한다.
set shmsys:shminfo_shmmax = 7840000000 set shmsys:shminfo_shmmin = 1 set shmsys:shminfo_shmseg = 3000 set shmsys:shminfo_shmmni = 10000
이의 적용된 값을 확인하기 위해서는 sysdef를 사용한다.
# sysdef : * IPC Shared Memory * 7840000000 max shared memory segment size (SHMMAX) 1 min shared memory segment size (SHMMIN) 10000 shared memory identifiers (SHMMNI) 3000 max attached shm segments per process (SHMSEG) *
공유 메모리 모듈의 로드 여부는 modinfo로서 확인 할 수 있다.
# modinfo | grep shmsys 34 1027c24e 2700 52 1 shmsys (System V shared memory) 34 1027c24e 2700 52 1 shmsys (32-bit System V shared memory)