λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
ComputerScience πŸ“š/운영체제

[OS] IPC μ‹œμŠ€ν…œμ˜ 사둀(Examples of IPC Systems)

by μ•ˆμ£Όν˜• 2022. 2. 10.

 

IPC μ‹œμŠ€ν…œμ˜ 사둀(Examples of IPC Systems)

 

 

[OS] ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신(Interprocess Communication, IPC)

ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신(IPC) 운영체제 λ‚΄μ—μ„œ μ‹€ν–‰λ˜λŠ” 병행 ν”„λ‘œμ„ΈμŠ€λ“€μ€ λ…λ¦½μ μ΄κ±°λ‚˜ λ˜λŠ” ν˜‘λ ₯적인 ν”„λ‘œμ„ΈμŠ€ 듀일 수 μžˆμŠ΅λ‹ˆλ‹€. ν”„λ‘œμ„ΈμŠ€κ°€ μ‹œμŠ€ν…œμ—μ„œ μ‹€ν–‰ 쀑인 λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€λ“€κ³Ό 데이터λ₯Ό 곡

dkswnkk.tistory.com

이전에 IPC의 κ°œλ…μ— λŒ€ν•΄ μ‚΄νŽ΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€. μ΄λ²ˆμ—λŠ” λ„€ 가지 λ‹€λ₯Έ IPC μ‹œμŠ€ν…œμ˜ 사둀에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€. 

  1. POSIX 곡유 λ©”λͺ¨λ¦¬(POSIX Shared Memory)
  2. Mach λ©”μ‹œμ§€ 전달(Mach Message Passing)
  3. Windows
  4. νŒŒμ΄ν”„(Pipes)

 

 

1. POSIX 곡유 λ©”λͺ¨λ¦¬(POSIX Shared Memory)

곡유 λ©”λͺ¨λ¦¬ λ©”μ‹œμ§€μ™€ 전달을 ν¬ν•¨ν•˜μ—¬ POSIX μ‹œμŠ€ν…œμ„ μœ„ν•œ λ‹€μˆ˜μ˜ IPC 기법이 μ‚¬μš© κ°€λŠ₯ν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œ 곡유 λ©”λͺ¨λ¦¬λ₯Ό μœ„ν•œ POSIX APIλ₯Ό μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 POSIX 곡유 λ©”λͺ¨λ¦¬λŠ” λ©”λͺ¨λ¦¬-사상 νŒŒμΌμ„ μ‚¬μš©ν•˜μ—¬ κ΅¬ν˜„λ©λ‹ˆλ‹€. λ©”λͺ¨λ¦¬-사상 νŒŒμΌμ€ 곡유 λ©”λͺ¨λ¦¬μ˜ νŠΉμ • μ˜μ—­μ„ 파일과 μ—°κ΄€μ‹œν‚΅λ‹ˆλ‹€. ν”„λ‘œμ„ΈμŠ€λŠ” λ¨Όμ € μ•„λž˜μ™€ 같이 shm_open() μ‹œμŠ€ν…œ μ½œμ„ μ‚¬μš©ν•˜μ—¬ 곡유 λ©”λͺ¨λ¦¬ 객체λ₯Ό 생성해야 ν•©λ‹ˆλ‹€.

fd = shm_open(name, O_CREATE | O_RDWR, 0666);

첫 번째 μΈμžλŠ” 곡유 λ©”λͺ¨λ¦¬ 객체의 이름을 μ§€μ •ν•©λ‹ˆλ‹€. 곡유 λ©”λͺ¨λ¦¬μ— μ ‘κ·Όν•˜κ³ μž ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€λŠ” 이 이름을 ν†΅ν•˜μ—¬ 객체λ₯Ό μ–ΈκΈ‰ν•©λ‹ˆλ‹€. μ΄μ–΄μ„œ 두 번째 μΈμžλŠ” 객체가 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ μƒμ„±λ˜κ³ (O_CREATE) κ°μ²΄λŠ” 읽기와 μ“°κΈ°κ°€ κ°€λŠ₯ν•œ μƒνƒœλ‘œ μ—΄λ¦°λ‹€λŠ” 것을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€(O_RDWR). λ§ˆμ§€λ§‰ μΈμžλŠ” 곡유 λ©”λͺ¨λ¦¬ 객체에 파일-μ ‘κ·Ό ν—ˆκ°€κΆŒμ„ λΆ€μ—¬ν•©λ‹ˆλ‹€. shm_open()이 μ„±κ³΅ν•˜λ©΄ 곡유 λ©”λͺ¨λ¦¬ 객체λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ •μˆ˜ν˜• 파일 μ„€λͺ…μžλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

 κ°μ²΄κ°€ μ„€μ •λ˜λ©΄ ftruncate() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 객체의 크기λ₯Ό λ°”μ΄νŠΈ λ‹¨μœ„λ‘œ μ„€μ •ν•©λ‹ˆλ‹€. λ‹€μŒκ³Ό 같은 ν˜ΈμΆœμ€ 객체의 크기λ₯Ό 4096λ°”μ΄νŠΈλ‘œ μ„€μ •ν•©λ‹ˆλ‹€.

ftruncate(fd, 4096);

 λ§ˆμ§€λ§‰μœΌλ‘œ mmap() ν•¨μˆ˜κ°€ 곡유 λ©”λͺ¨λ¦¬ 객체λ₯Ό ν¬ν•¨ν•˜λŠ” λ©”λͺ¨λ¦¬-사상 νŒŒμΌμ„ κ΅¬μΆ•ν•©λ‹ˆλ‹€.mmap() ν•¨μˆ˜λŠ” 곡유 λ©”λͺ¨λ¦¬ 객체에 μ ‘κ·Όν•  λ•Œ μ‚¬μš©λ  λ©”λͺ¨λ¦¬-사상 파일의 포인터λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

 μ•„λž˜ 두 μ½”λ“œμ˜ ν”„λ‘œκ·Έλž¨μ€ 곡유 λ©”λͺ¨λ¦¬λ₯Ό κ΅¬ν˜„ν•˜κΈ° μœ„ν•˜μ—¬ μƒμ‚°μž-μ†ŒλΉ„μž λͺ¨λΈμ„ μ‚¬μš©ν•©λ‹ˆλ‹€. 

μ½”λ“œ 1) POSIX곡유 λ©”λͺ¨λ¦¬ APIλ₯Ό μ„€λͺ…ν•˜λŠ” μƒμƒμž ν”„λ‘œμ„ΈμŠ€

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>

#include <sys/mman.h>

int main()
{
    /* the size (in bytes) of shared memory object */
    const int SIZE = 4096;
    /* name of the shared memory object */
    const char *name = "OS";
    /* strings written to shared memory */
    const char *message 0 = "Hello";
    const char *message 1 = "World!";
    
    /* shared memory file descriptor */
    int fd;
    /* pointer to shared memory obect */
    char *ptr;
    
    /* create the shared memory object */
    fd = shm open(name,O CREAT | O RDWR,0666);
    
    /* configure the size of the shared memory object */
    ftruncate(fd, SIZE);
    
    /* memory map the shared memory object */
    ptr = (char *)
    mmap(0, SIZE, PROT READ | PROT WRITE, MAP SHARED, fd, 0);
    
    /* write to the shared memory object */
    sprintf(ptr,"%s",message 0);
    ptr += strlen(message 0);
    sprintf(ptr,"%s",message 1);
    ptr += strlen(message 1);
    
    return 0;
}

 

μ½”λ“œ 2) POSIX 곡유 λ©”λͺ¨λ¦¬ APIλ₯Ό μ„€λͺ…ν•˜λŠ” μ†ŒλΉ„μž ν”„λ‘œμ„ΈμŠ€

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>

#include <sys/mman.h>
int main()
{
    /* the size (in bytes) of shared memory object */
    const int SIZE = 4096;
    /* name of the shared memory object */
    const char *name = "OS";
    /* shared memory file descriptor */
    int fd;
    /* pointer to shared memory obect */
    char *ptr;
    
    /* open the shared memory object */
    fd = shm open(name, O RDONLY, 0666);
    
    /* memory map the shared memory object */
    ptr = (char *)
    mmap(0, SIZE, PROT READ | PROT WRITE, MAP SHARED, fd, 0);
    
    /* read from the shared memory object */
    printf("%s",(char *)ptr);
    
    /* remove the shared memory object */
    shm unlink(name);
    
    return 0;
}

 

μƒμ‚°μžλŠ” 곡유 λ©”λͺ¨λ¦¬ 객체λ₯Ό κ΅¬μΆ•ν•˜κ³  곡유 λ©”λͺ¨λ¦¬μ— 데이터λ₯Ό μ“°κ³ , μ†ŒλΉ„μžλŠ” 곡유 λ©”λͺ¨λ¦¬μ—μ„œ 데이터λ₯Ό μ½μŠ΅λ‹ˆλ‹€. μœ„ μ½”λ“œ 1μ—μ„œ 보인 μƒμ‚°μžλŠ” OS라고 λͺ…λͺ…λœ 곡유 λ©”λͺ¨λ¦¬ 객체λ₯Ό μƒμ„±ν•˜κ³  λ¬Έμžμ—΄ "Hello World"λ₯Ό 곡유 λ©”λͺ¨λ¦¬μ— μ”λ‹ˆλ‹€. ν”„λ‘œκ·Έλž¨μ€ μ§€μ •λœ 크기의 곡유 λ©”λͺ¨λ¦¬ 객체λ₯Ό λ©”λͺ¨λ¦¬μ— μ‚¬μƒν•˜κ³  객체에 μ“°κΈ° κΆŒν•œμ„ λΆ€μ—¬ν•©λ‹ˆλ‹€. MAP_SHARED ν”Œλž˜κ·ΈλŠ” 곡유 λ©”λͺ¨λ¦¬ 객체에 변경이 λ°œμƒν•˜λ©΄ 객체λ₯Ό κ³΅μœ ν•˜λŠ” λͺ¨λ“  ν”„λ‘œμ„ΈμŠ€κ°€ μ΅œμ‹ μ˜ 값을 μ ‘κ·Όν•˜κ²Œ λœλ‹€λŠ” 것을 μ§€μ •ν•©λ‹ˆλ‹€. 곡유 λ©”λͺ¨λ¦¬ 객체에 μ“°κΈ° μž‘μ—…μ„ ν•  λ•Œ sprintf() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³  좜λ ₯ ν˜•μ‹μ΄ μ™„μ„±λœ λ¬Έμžμ—΄μ€ ptr이 κ°€λ¦¬ν‚€λŠ” 곡유 λ©”λͺ¨λ¦¬ 객체에 μ“°μΈλ‹€λŠ” 것을 μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. μ“°κΈ° μž‘μ—…μ΄ μ„±κ³΅ν•˜λ©΄ 쓰인 λ°”μ΄νŠΈ 수만큼 포인터λ₯Ό λ°˜λ“œμ‹œ μ¦κ°€μ‹œμΌœμ•Ό ν•©λ‹ˆλ‹€.

 μ½”λ“œ 2의 μ†ŒλΉ„μž ν”„λ‘œμ„ΈμŠ€λŠ” 곡유 λ©”λͺ¨λ¦¬μ˜ λ‚΄μš©μ„ 읽고 좜λ ₯ν•©λ‹ˆλ‹€. λ˜ν•œ μ†ŒλΉ„μžλŠ” shm_unlink() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ 접근이 λλ‚œ 곡유 λ©”λͺ¨λ¦¬λ₯Ό μ œκ±°ν•©λ‹ˆλ‹€.

 

 

2. Mach λ©”μ‹œμ§€ 전달(Mach Message Passing)

λ‹€μŒ λ©”μ‹œμ§€ μ „λ‹¬μ˜ 예둜 Mach 운영체제λ₯Ό κ³ λ €ν•΄ λ΄…μ‹œλ‹€. MachλŠ” 특히 λΆ„μ‚° μ‹œμŠ€ν…œμš©μœΌλ‘œ μ„€κ³„λ˜μ—ˆμ§€λ§Œ macOS 및 iOS μš΄μ˜μ²΄μ œμ— ν¬ν•¨λœ 사싀이 μž…μ¦ν•˜λ“―μ΄ λ°μŠ€ν¬ν†± 및 λͺ¨λ°”일 μ‹œμŠ€ν…œμ—λ„ μ ν•©ν•©λ‹ˆλ‹€.

 Mach 컀널은 ν”„λ‘œμ„ΈμŠ€μ™€ μœ μ‚¬ν•˜μ§€λ§Œ μ œμ–΄ μŠ€λ ˆλ“œκ°€ 많고 κ΄€λ ¨ μžμ›μ΄ 적은 닀쀑 νƒœμŠ€ν¬μ˜ 생성 및 제거λ₯Ό μ§€μ›ν•©λ‹ˆλ‹€. λͺ¨λ“  νƒœμŠ€ν¬ κ°„ 톡신을 ν¬ν•¨ν•˜μ—¬ Machμ—μ„œ λŒ€λΆ€λΆ„μ˜ 톡신은 λ©”μ‹œμ§€λ‘œ μˆ˜ν–‰λ©λ‹ˆλ‹€. Machμ—μ„œ 포트(port)라고 ν•˜λŠ” λ©”μΌλ°•μŠ€λ‘œ λ©”μ‹œμ§€λ₯Ό μ£Όκ³ λ°›μŠ΅λ‹ˆλ‹€. ν¬νŠΈλŠ” 크기가 μ •ν•΄μ Έ 있고 단방ν–₯μž…λ‹ˆλ‹€. μ–‘λ°©ν–₯ 톡신인 경우 λ©”μ‹œμ§€κ°€ ν•œ 포트둜 μ „μ†‘λ˜κ³  응닡이 λ³„λ„μ˜ 응닡 포트둜 μ „μ†‘λ©λ‹ˆλ‹€. 각 ν¬νŠΈμ—λŠ” μ—¬λŸ¬ μ†‘μ‹ μžκ°€ μžˆμ„ 수 μžˆμ§€λ§Œ μˆ˜μ‹ μžλŠ” 였직 ν•˜λ‚˜λ§Œ μ‘΄μž¬ν•©λ‹ˆλ‹€. MachλŠ” 포트λ₯Ό μ‚¬μš©ν•˜μ—¬ νƒœμŠ€ν¬, μŠ€λ ˆλ“œ, λ©”λͺ¨λ¦¬ 및 ν”„λ‘œμ„Έμ„œμ™€ 같은 μžμ›μ„ λ‚˜νƒ€λ‚΄λ©°, λ©”μ‹œμ§€ 전달은 μ΄λŸ¬ν•œ μ‹œμŠ€ν…œ μžμ› 및 μ„œλΉ„μŠ€μ™€ μƒν˜Έ μž‘μš©ν•˜κΈ° μœ„ν•œ 객체 지ν–₯ μ ‘κ·Ό 방식을 μ œκ³΅ν•©λ‹ˆλ‹€. λ™μΌν•œ 호슀트 λ˜λŠ” λΆ„μ‚° μ‹œμŠ€ν…œμ˜ 별도 호슀트의 두 포트 μ‚¬μ΄μ—μ„œ λ©”μ‹œμ§€ 전달이 λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 κ° ν¬νŠΈμ—λŠ” κ·Έ ν¬νŠΈμ™€ μƒν˜Έ μž‘μš©ν•˜λŠ” 데 ν•„μš”ν•œ μžκ²©μ„ μ‹λ³„ν•˜λŠ” 포트 κΆŒν•œ 집합이 μ—°κ΄€λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, νƒœμŠ€ν¬κ°€ ν¬νŠΈμ—μ„œ λ©”μ‹œμ§€λ₯Ό μˆ˜μ‹ ν•˜λ €λ©΄ ν•΄λ‹Ή ν¬νŠΈμ— λŒ€ν•΄ MACH_PORT_RIGHT_RECEIVE 자격이 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€. 포트λ₯Ό μƒμ„±ν•œ νƒœμŠ€ν¬κ°€ ν•΄λ‹Ή 포트의 μ†Œμœ μžμ΄λ©°, μ†Œμœ μžλŠ” ν•΄λ‹Ή ν¬νŠΈμ—μ„œ λ©”μ‹œμ§€λ₯Ό μˆ˜μ‹ ν•  수 μžˆλŠ” μœ μΌν•œ νƒœμŠ€ν¬μž…λ‹ˆλ‹€. 포트의 μ†Œμœ μžλŠ” 포트의 μžκ²©μ„ μ‘°μž‘ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ μ‘°μž‘μ€ 일반적으둜 응닡 포트λ₯Ό μ„€μ •ν•  λ•Œ μˆ˜ν–‰λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, νƒœμŠ€ν¬ T1이 포트 P1을 μ†Œμœ ν•˜κ³  νƒœμŠ€ν¬ P2κ°€ μ†Œμœ ν•œ 포트 P2에 λ©”μ‹œμ§€λ₯Ό μ „μ†‘ν•œλ‹€κ³  κ°€μ •ν•©μ‹œλ‹€. T1이 T2λ‘œλΆ€ν„° 응닡을 λ°›μœΌλ €λ©΄ T2에 포트 P1에 λŒ€ν•œ MACH_PORT_RIGHT_SEND κΆŒν•œμ„ λΆ€μ—¬ν•΄μ•Ό ν•©λ‹ˆλ‹€. 포트 κΆŒν•œμ˜ μ†Œμœ κΆŒμ€ νƒœμŠ€ν¬μ—κ²Œ μ£Όμ–΄μ§‘λ‹ˆλ‹€. 즉, λ™μΌν•œ νƒœμŠ€ν¬μ— μ†ν•˜λŠ” 두 개의 μŠ€λ ˆλ“œλŠ” 각 μŠ€λ ˆλ“œμ™€ κ΄€λ ¨λœ μŠ€λ ˆλ“œ-별 포트λ₯Ό 톡해 λ©”[μ‹œμ§€λ₯Ό κ΅ν™˜ν•˜μ—¬ μ‰½κ²Œ 톡신할 수 μžˆμŠ΅λ‹ˆλ‹€.

 νƒœμŠ€ν¬κ°€ μƒμ„±λ˜λ©΄ Task Self ν¬νŠΈμ™€ Notify ν¬νŠΈλΌλŠ” 두 개의 νŠΉλ³„ν•œ ν¬νŠΈλ„ μƒμ„±λ©λ‹ˆλ‹€. 컀널은 Task Self ν¬νŠΈμ— λŒ€ν•œ μˆ˜μ‹  κΆŒν•œμ„ 가지고 μžˆμ–΄ νƒœμŠ€ν¬κ°€ 컀널에 λ©”μ‹œμ§€λ₯Ό 보낼 수 μžˆμŠ΅λ‹ˆλ‹€. 컀널은 이벀트 λ°œμƒ μ•Œλ¦Όμ„ μž‘μ—…μ˜ Notify 포트(λ¬Όλ‘  νƒœμŠ€ν¬κ°€ μˆ˜μ‹  κΆŒν•œμ„ 가지고 있음)둜 보낼 수 μžˆμŠ΅λ‹ˆλ‹€.

 mach_port_allocate() ν•¨μˆ˜ ν˜ΈμΆœμ€ μƒˆ 포트λ₯Ό μž‘μ„±ν•˜κ³  λ©”μ‹œμ§€ 큐λ₯Ό μœ„ν•œ 곡간을 ν• λ‹Ήν•©λ‹ˆλ‹€. λ˜ν•œ ν¬νŠΈμ— λŒ€ν•œ κΆŒν•œμ„ μ‹λ³„ν•©λ‹ˆλ‹€. 각 포트 κΆŒν•œμ€ ν•΄λ‹Ή 포트의 이름을 λ‚˜νƒ€λ‚΄λ©° 포트의 κΆŒν•œμ„ ν†΅ν•΄μ„œλ§Œ μ•‘μ„ΈμŠ€ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 포트 이름은 λ‹¨μˆœν•œ μ •μˆ˜ 값이며 UNIX 파일 λ””μŠ€ν¬λ¦½ν„°μ™€ 맀우 μœ μ‚¬ν•˜κ²Œ μž‘λ™ν•©λ‹ˆλ‹€. λ‹€μŒ μ˜ˆμ œλŠ” 이 APIλ₯Ό μ‚¬μš©ν•˜μ—¬ 포트λ₯Ό μƒμ„±ν•˜λŠ” 방법을 λ³΄μ—¬μ€λ‹ˆλ‹€.

mach port t port; // 포트 κΆŒν•œμ˜ 이름
mach port allocate(
     mach task self(), // a task referring to itself
     MACH PORT RIGHT RECEIVE, // the right for this port
     &port); // the name of the port right

 

 κ° νƒœμŠ€ν¬λŠ” λ˜ν•œ λΆ€νŠΈμŠ€νŠΈλž© ν¬νŠΈμ— μ•‘μ„ΈμŠ€ ν•  수 μžˆμ–΄μ„œ νƒœμŠ€ν¬κ°€ μƒμ„±ν•œ 포트λ₯Ό μ‹œμŠ€ν…œ μ „μ²΄μ˜ λΆ€νŠΈμŠ€νŠΈλž© μ„œλ²„μ— 등둝할 수 μžˆμŠ΅λ‹ˆλ‹€. ν¬νŠΈκ°€ λΆ€νŠΈμŠ€νŠΈλž© μ„œλ²„μ— λ“±λ‘λ˜λ©΄ λ‹€λ₯Έ νƒœμŠ€ν¬κ°€ 이 λ ˆμ§€μŠ€νŠΈλ¦¬μ—μ„œ 포트λ₯Ό κ²€μƒ‰ν•˜μ—¬ 포트둜 λ©”μ‹œμ§€λ₯Ό 보낼 수 μžˆλŠ” κΆŒν•œμ„ 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

 κ° ν¬νŠΈμ™€ κ΄€λ ¨λœ νλŠ” 크기가 μ œν•œλ˜μ–΄ 있으며 μ²˜μŒμ—λŠ” λΉ„μ–΄ μžˆμŠ΅λ‹ˆλ‹€. λ©”μ‹œμ§€κ°€ 포트둜 μ „μ†‘λ˜λ©΄ 큐에 λ³΅μ‚¬λ©λ‹ˆλ‹€. λͺ¨λ“  λ©”μ‹œμ§€λŠ” μ•ˆμ •μ μœΌλ‘œ μ „λ‹¬λ˜λ©° λ™μΌν•œ μš°μ„ μˆœμœ„λ₯Ό κ°€μ§‘λ‹ˆλ‹€. MachλŠ” λ™μΌν•œ μ†‘μ‹ μžμ˜ μ—¬λŸ¬ λ©”μ‹œμ§€κ°€ μ„ μž…μ„ μΆœ(FIFO) μˆœμ„œλ‘œ 큐에 μ‚½μž…ν•˜μ§€λ§Œ μ ˆλŒ€μ  μˆœμ„œλ₯Ό 보μž₯ν•˜μ§€λŠ” μ•ŠμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, 두 λͺ…μ˜ μ†‘μ‹ μžκ°€ 보낸 λ©”μ‹œμ§€λŠ” μž„μ˜μ˜ μˆœμ„œλ‘œ 큐에 μ €μž₯λ©λ‹ˆλ‹€.

 Mach λ©”μ‹œμ§€μ—λŠ” λ‹€μŒ 두 ν•„λ“œλ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€.

  • κ³ μ • 크기의 λ©”μ‹œμ§€ 헀더. ν—€λ”λŠ” λ©”μ‹œμ§€ 크기, μ†ŒμŠ€ 및 λŒ€μƒ 포트λ₯Ό ν¬ν•¨ν•œ λ©”μ‹œμ§€μ— κ΄€ν•œ 메타 데이터λ₯Ό ν¬ν•¨ν•œλ‹€. 일반적으둜 솑신 μŠ€λ ˆλ“œλŠ” 응닡을 μ˜ˆμƒν•˜λ―€λ‘œ μ†ŒμŠ€μ˜ 포트 이름이 μˆ˜μ‹  νƒœμŠ€ν¬λ‘œ μ „λ‹¬λ˜μ–΄ 응닡을 λ³΄λ‚΄λŠ” 데 "λ°˜ν™˜ μ£Όμ†Œ"둜 μ‚¬μš©ν•  수 μžˆλ‹€.
  • 데이터λ₯Ό ν¬ν•¨ν•˜λŠ” κ°€λ³€ 크기 본체

 λ©”μ‹œμ§€λŠ” λ‹¨μˆœν•˜κ±°λ‚˜ λ³΅μž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ°„λ‹¨ν•œ λ©”μ‹œμ§€λŠ” 컀널에 μ˜ν•΄ ν•΄μ„λ˜μ§€ μ•ŠλŠ” κ΅¬μ‘°ν™”λ˜μ§€ μ•Šμ€ λ³΄ν†΅μ˜ μ‚¬μš©μž 데이터λ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€. λ³΅μž‘ν•œ λ©”μ‹œμ§€λŠ” "out-of-line" 데이터λ₯Ό ν¬ν•¨ν•˜λŠ” λ©”λͺ¨λ¦¬ μœ„μΉ˜μ— λŒ€ν•œ 포인터λ₯Ό ν¬ν•¨ν•˜κ±°λ‚˜ λ‹€λ₯Έ νƒœμŠ€ν¬μ— 포트 κΆŒν•œμ„ μ „μ†‘ν•˜λŠ” 데 μ‚¬μš©λ  수 μžˆμŠ΅λ‹ˆλ‹€. Out-of-line 데이터 ν¬μΈν„°λŠ” λ©”μ‹œμ§€κ°€ λ§Žμ€ μ–‘μ˜ 데이터λ₯Ό 전달해야 ν•  λ•Œ 특히 μœ μš©ν•©λ‹ˆλ‹€. κ°„λ‹¨ν•œ λ©”μ‹œμ§€λŠ” λ©”μ‹œμ§€μ˜ 데이터λ₯Ό λ³΅μ‚¬ν•˜κ³  νŒ¨ν‚€μ§•ν•΄μ•Ό ν•©λ‹ˆλ‹€. Out-of-line 데이터 μ „μ†‘μ—λŠ” 데이터가 μ €μž₯된 λ©”λͺ¨λ¦¬ μœ„μΉ˜λ₯Ό κ°€λ¦¬ν‚€λŠ” ν¬μΈν„°λ§Œ ν•„μš”ν•©λ‹ˆλ‹€.

 mach_msg() ν•¨μˆ˜λŠ” λ©”μ‹œμ§€λ₯Ό 보내고 λ°›λŠ” ν‘œμ€€ APIμž…λ‹ˆλ‹€. ν•¨μˆ˜λŠ” λ§€κ°œλ³€μˆ˜ 쀑 ν•˜λ‚˜κ°€ MACH_SEND_MSG λ˜λŠ” MACH_RCV_MSG값을 가지며 솑신 λ˜λŠ” μˆ˜μ‹  μ—°μ‚°μžμΈμ§€λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€. 이제 ν΄λΌμ΄μ–ΈνŠΈ νƒœμŠ€ν¬κ°€ μ„œλ²„ νƒœμŠ€ν¬μ— κ°„λ‹¨ν•œ λ©”μ‹œμ§€λ₯Ό 보낼 λ•Œ μ‚¬μš©λ˜λŠ” 방법을 μ„€λͺ…ν•˜κ² μŠ΅λ‹ˆλ‹€. ν΄λΌμ΄μ–ΈνŠΈ 및 μ„œλ²„ νƒœμŠ€ν¬μ™€ 각각 μ—°κ΄€λœ 두 개의 포트(client와 server)κ°€ μžˆλ‹€κ³  κ°€μ •ν•©μ‹œλ‹€. μ•„λž˜ μ½”λ“œλŠ” ν΄λΌμ΄μ–ΈνŠΈ νƒœμŠ€ν¬κ°€ 헀더λ₯Ό κ΅¬μ„±ν•˜κ³  μ„œλ²„λ‘œ λ©”μ‹œμ§€λ₯Ό λ³΄λ‚΄λŠ” κ²ƒλΏλ§Œ μ•„λ‹ˆλΌ ν΄λΌμ΄μ–ΈνŠΈκ°€ 보낸 λ©”μ‹œμ§€λ₯Ό λ°›λŠ” μ„œλ²„ νƒœμŠ€ν¬λ₯Ό λ³΄μ—¬μ€λ‹ˆλ‹€.

Machμ—μ„œ λ©”μ‹œμ§€ 전달을 μ„€λͺ…ν•˜λŠ” 예제 ν”„λ‘œκ·Έλž¨

#include<mach/mach.h>

struct message {
    mach msg header t header; int data;
};

mach port t client;
mach port t server;

/* ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œ */
struct message message;

// 헀더λ₯Ό ꡬ좕
message.header.msgh size = sizeof(message);
message.header.msgh remote port = server;
message.header.msgh local port = client;

// λ©”μ‹œμ§€λ₯Ό μ†‘μ‹ ν•œλ‹€.
mach msg(&message.header, // λ©”μ‹œμ§€ 헀더
         MACH_SEND_MSG, // λ©”μ‹œμ§€ 솑신
         sizeof(message), // μ†‘μ‹ λœ λ©”μ‹œμ§€ 크기
         0, // μˆ˜μ‹  λ©”μ‹œμ§€μ˜ μ΅œλŒ€ 크기 - ν•„μš”μ—†μŒ
         MACH_PORT_NULL, // μˆ˜μ‹  포트의 이름 포트 μ—†μŒ ν•„μš”μ—†μŒ
         MACH_MSG_TIMEOUT_NONE, // νƒ€μž„μ•„μ›ƒ μ„€μ • μ—†μŒ
         MACH_PORT_NULL // 포트 μ—†μŒ
);


/* μ„œλ²„ μ½”λ“œ */

struct message message;

// λ©”μ‹œμ§€λ₯Ό μˆ˜μ‹ ν•œλ‹€.
mach msg(&message.header, // λ©”μ‹œμ§€ 헀더
         MACH_RCV_MSG, // λ©”μ‹œμ§€ μˆ˜μ‹ 
         0, // μ†‘μ‹ λœ λ©”μ‹œμ§€ 크기
         sizeof(message), // μˆ˜μ‹  λ©”μ‹œμ§€μ˜ μ΅œλŒ€ 크기
         server,    // μˆ˜μ‹  포트의 이름
         MACH_MSG_TIMEOUT_NONE, // νƒ€μž„ 아웃 μ„€μ • μ—†μŒ
         MACH_PORT_NULL // 포트 μ—†μŒ
);

 

 mach_mag() ν•¨μˆ˜ ν˜ΈμΆœμ€ λ©”μ‹œμ§€ 전달을 μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ μ‚¬μš©μž ν”„λ‘œκ·Έλž¨μ— μ˜ν•΄ ν˜ΈμΆœλ©λ‹ˆλ‹€. 그런 λ‹€μŒ mach_msg()λŠ” mah_msg_trap() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€. μ΄λŠ” mah 컀널에 λŒ€ν•œ μ‹œμŠ€ν…œ μ½œμž…λ‹ˆλ‹€. 컀널 λ‚΄μ—μ„œ mach_msg_trap()은 mach_msg_overwrite_trap() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ λ©”μ‹œμ§€μ˜ μ‹€μ œ 전달을 μ²˜λ¦¬ν•©λ‹ˆλ‹€.

 μ†‘μˆ˜μ‹  μž‘μ—… μžμ²΄λŠ” μœ΅ν†΅μ„±μ΄ μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, λ©”μ‹œμ§€κ°€ 포트둜 μ „μ†‘λ˜μ—ˆμ„ λ•Œ, 큐가 가득 찼을 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. 큐가 가득 차지 μ•ŠμœΌλ©΄ λ©”μ‹œμ§€κ°€ 큐에 λ³΅μ‚¬λ˜κ³  전솑 μž‘μ—…μ΄ κ³„μ†λ©λ‹ˆλ‹€. 포트의 큐가 가득 μ°¬ 경우 μ†‘μ‹ μžλŠ” mach_msg()의 λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 λ‹€μŒ 쀑 ν•˜λ‚˜λ₯Ό 선택할 수 μžˆμŠ΅λ‹ˆλ‹€.

  1. 큐에 곡간이 생길 λ•ŒκΉŒμ§€ λ¬΄κΈ°ν•œ κΈ°λ‹€λ¦°λ‹€.
  2. μ΅œλŒ€ n λ°€λ¦¬μ΄ˆ λ™μ•ˆ κΈ°λ‹€λ¦°λ‹€.
  3. 기닀리지 말고 μ¦‰μ‹œ λ³΅κ·€ν•œλ‹€.
  4. λ©”μ‹œμ§€λ₯Ό μΌμ‹œμ μœΌλ‘œ μΊμ‹œ ν•œλ‹€. λ©”μ‹œμ§€κ°€ μ „μ†‘λ˜λŠ” 큐가 가득 차더라도 μš΄μ˜μ²΄μ œμ— μ „λ‹¬ν•˜μ—¬ λ³΄μ‘΄ν•œλ‹€. λ©”μ‹œμ§€λ₯Ό 큐에 넣을 수 μžˆμ„ λ•Œ, 톡지 λ©”μ‹œμ§€κ°€ μ†‘μ‹ μžμ—κ²Œ μ „μ†‘λœλ‹€. 큐가 가득 찼을 경우 솑신 μŠ€λ ˆλ“œλ§ˆλ‹€ ν•˜λ‚˜μ˜ λ©”μ‹œμ§€λ§Œ 컀널에 보관할 수 μžˆλ‹€.

λ§ˆμ§€λ§‰ 4번 μ˜΅μ…˜μ€ μ„œλ²„ νƒœμŠ€ν¬λ₯Ό μœ„ν•œ κ²ƒμž…λ‹ˆλ‹€. μš”μ²­μ„ μ™„λ£Œν•œ ν›„ μ„œλ²„ νƒœμŠ€ν¬λŠ” μ„œλΉ„μŠ€λ₯Ό μš”μ²­ν•œ νƒœμŠ€ν¬μ— μΌνšŒμ„± 응닡을 보내야 ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ ν΄λΌμ΄μ–ΈνŠΈμ˜ 응닡 ν¬νŠΈκ°€ 가득 μ°¬ κ²½μš°μ—λ„ λ‹€λ₯Έ μ„œλΉ„μŠ€ μš”μ²­μ„ 계속 μ„œλΉ„μŠ€ν•΄μ•Ό ν•©λ‹ˆλ‹€.

 λ©”μ‹œμ§€ μ‹œμŠ€ν…œμ˜ μ£Όμš” λ¬Έμ œμ μ€ 일반적으둜 μ†‘μ‹ μžμ˜ ν¬νŠΈμ—μ„œ μˆ˜μ‹ μžμ˜ 포트둜 λ©”μ‹œμ§€λ₯Ό 볡사해야 ν•˜λ―€λ‘œ λ°œμƒν•˜λŠ” μ„±λŠ₯ μ €ν•˜μž…λ‹ˆλ‹€. Mach λ©”μ‹œμ§€ μ‹œμŠ€ν…œμ€ 가상 λ©”λͺ¨λ¦¬ 관리 κΈ°μˆ μ„ μ‚¬μš©ν•˜μ—¬ 볡사 연산을 ν”Όν•˜λ €κ³  ν•©λ‹ˆλ‹€. 기본적으둜 MachλŠ” μ†‘μ‹ μžμ˜ λ©”μ‹œμ§€κ°€ ν¬ν•¨λœ μ£Όμ†Œ 곡간을 μˆ˜μ‹ μžμ˜ μ£Όμ†Œ 곡간에 λ§€ν•‘ν•©λ‹ˆλ‹€. λ”°λΌμ„œ μ†‘μ‹ μžμ™€ μˆ˜μ‹ μž λͺ¨λ‘ λ™μΌν•œ λ©”λͺ¨λ¦¬μ— μ•‘μ„ΈμŠ€ ν•˜λ―€λ‘œ λ©”μ‹œμ§€ μžμ²΄λŠ” μ‹€μ œλ‘œ λ³΅μ‚¬λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 이 λ©”μ‹œμ§€ 관리 κΈ°μˆ μ€ μ„±λŠ₯을 크게 ν–₯μƒμ‹œν‚€μ§€λ§Œ 같은 μ‹œμŠ€ν…œ λ‚΄ λ©”μ‹œμ§€μ—λ§Œ μž‘λ™ν•©λ‹ˆλ‹€.

 

3. Windows

Windows μš΄μ˜μ²΄μ œλŠ” λͺ¨λ“ˆν™”λ₯Ό μ΄μš©ν•˜μ—¬ κΈ°λŠ₯을 ν–₯μƒμ‹œν‚€κ³  μƒˆλ‘œμš΄ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λŠ” μ‹œκ°„μ„ κ°μ†Œμ‹œν‚¨ μ΅œμ‹  μ„€κ³„μ˜ μ˜ˆμž…λ‹ˆλ‹€. WindowsλŠ” 닀쀑 운영 ν™˜κ²½ λ˜λŠ” μ„œλΈŒμ‹œμŠ€ν…œμ„ μ§€μ›ν•˜λ©°, μ‘μš© ν”„λ‘œκ·Έλž¨μ€ λ©”μ‹œμ§€ 전달 기법을 톡해 이듀과 ν†΅μ‹ ν•©λ‹ˆλ‹€. λ”°λΌμ„œ μ‘μš© ν”„λ‘œκ·Έλž¨μ€ μ„œλΈŒ μ‹œμŠ€ν…œ μ„œλ²„μ˜ ν΄λΌμ΄μ–ΈνŠΈλ‘œ κ°„μ£Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 Windows의 λ©”μ‹œμ§€ 전달 μ„€λΉ„λŠ” κ³ κΈ‰ 둜컬 ν”„λ‘œμ‹œμ € 호좜 μ„€λΉ„(advanced local procedure call facility, ALPC)라 λΆˆλ¦½λ‹ˆλ‹€. ALPCλŠ” 동일 기계상에 μžˆλŠ” 두 ν”„λ‘œμ„ΈμŠ€ κ°„μ˜ 톡신에 μ‚¬μš©ν•©λ‹ˆλ‹€. 이것은 널리 μ‚¬μš©λ˜λŠ” ν‘œμ€€ 원격 ν”„λ‘œμ‹œμ € 호좜(RPC) 기법과 κ°™μœΌλ‚˜, Windows에 맞게 νŠΉλ³„νžˆ μ΅œμ ν™”λ˜μ—ˆμŠ΅λ‹ˆλ‹€. Mach와 μœ μ‚¬ν•˜κ²Œ, WindowsλŠ” 두 ν”„λ‘œμ„ΈμŠ€ 간에 연결을 κ΅¬μΆ•ν•˜κ³  μœ μ§€ν•˜κΈ° μœ„ν•΄ 포트 객체λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. WindowsλŠ” μ—°κ²° 포트(connection port)와 두 가지 μœ ν˜•μ˜ 포트λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

 μ„œλ²„ ν”„λ‘œμ„ΈμŠ€λŠ” λͺ¨λ“  ν”„λ‘œμ„ΈμŠ€κ°€ μ ‘κ·Όν•  수 μžˆλŠ” μ—°κ²° 포트 객체λ₯Ό κ³΅ν‘œν•©λ‹ˆλ‹€. ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλΈŒμ‹œμŠ€ν…œμœΌλ‘œλΆ€ν„° μ„œλΉ„μŠ€λ₯Ό 원할 경우, μ„œλ²„μ˜ μ—°κ²° 포트 객체에 λŒ€ν•œ 핸듀을 μ—΄κ³  μ—°κ²° μš”μ²­μ„ λ³΄λƒ…λ‹ˆλ‹€. 그러면 μ„œλ²„λŠ” 채널을 μƒμ„±ν•˜κ³  핸듀을 ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ λ°˜ν™˜ν•©λ‹ˆλ‹€. 채널은 ν•œ 쌍의 사적인 톡신 포트둜 κ΅¬μ„±λ˜λŠ”λ°, ν•˜λ‚˜λŠ” ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ μ„œλ²„λ‘œ λ©”μ‹œμ§€λ₯Ό 보내기 μœ„ν•œ 포트이고 λ‹€λ₯Έ ν•˜λ‚˜λŠ” μ„œλ²„μ—μ„œ ν΄λΌμ΄μ–ΈνŠΈλ‘œ λ©”μ‹œμ§€λ₯Ό 보내기 μœ„ν•œ ν¬νŠΈμž…λ‹ˆλ‹€. μΆ”κ°€μ μœΌλ‘œ 톡신 채널은 ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„κ°€ 응닡 λ©”μ‹œμ§€λ₯Ό 기닀리고 μžˆλŠ” λ™μ•ˆμ—λ„ λ‹€λ₯Έ μš”μ²­μ„ 받아듀일 수 μžˆλ„λ‘ 콜백 기법을 μ œκ³΅ν•©λ‹ˆλ‹€.

 ALPC 채널이 μƒμ„±λ˜λ©΄ λ‹€μŒ 3가지 쀑 ν•˜λ‚˜μ˜ λ©”μ‹œμ§€ 전달 κΈ°λ²•μ˜ ν•˜λ‚˜κ°€ μ„ νƒλ©λ‹ˆλ‹€.

  1. 256λ°”μ΄νŠΈκΉŒμ§€μ˜ μž‘μ€ λ©”μ‹œμ§€μ˜ 경우, 포트의 λ©”μ‹œμ§€ 큐가 쀑간 μ €μž₯μ†Œλ‘œ μ‚¬μš©λ˜κ³ , λ©”μ‹œμ§€λŠ” ν”„λ‘œμ„ΈμŠ€μ—μ„œ ν”„λ‘œμ„ΈμŠ€λ‘œ λ³΅μ‚¬λœλ‹€.
  2. λŒ€μš©λŸ‰ λ©”μ‹œμ§€λŠ” λ°˜λ“œμ‹œ μ„Ήμ…˜ 객체(section object)λ₯Ό ν†΅ν•˜μ—¬ μ „λ‹¬λ˜μ–΄μ•Ό ν•œλ‹€. μ„Ήμ…˜ κ°μ²΄λž€ 채널과 μ—°κ΄€λœ 곡유 λ©”λͺ¨λ¦¬μ˜ μ˜μ—­μ„ λ§ν•œλ‹€.
  3. λ°μ΄ν„°μ˜ 양이 λ„ˆλ¬΄ λ§Žμ•„μ„œ μ„Ήμ…˜ 객체에 μ €μž₯될 수 μ—†λŠ” 경우, μ„œλ²„ ν”„λ‘œμ„ΈμŠ€κ°€ ν΄λΌμ΄μ–ΈνŠΈμ˜ μ£Όμ†Œ 곡간을 직접 μ½κ±°λ‚˜ μ“Έ 수 μžˆλŠ” APIλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

 ν΄λΌμ΄μ–ΈνŠΈλŠ” 채널을 μ„€μ •ν•  λ•Œ λŒ€μš©λŸ‰ λ©”μ‹œμ§€ 전솑이 ν•„μš”ν•œμ§€ κ²°μ •ν•΄μ•Όλ§Œ ν•©λ‹ˆλ‹€. ν΄λΌμ΄μ–ΈνŠΈκ°€ λŒ€μš©λŸ‰ λ©”μ‹œμ§€λ₯Ό 보내야 ν•œλ‹€κ³  κ²°μ •ν•˜λ©΄ μ„Ήμ…˜ 객체의 생성을 μš”μ²­ν•©λ‹ˆλ‹€. λ§ˆμ°¬κ°€μ§€λ‘œ, μ„œλ²„μ˜ 응닡 λ©”μ‹œμ§€κ°€ λŒ€μš©λŸ‰μ΄λΌκ³  μ˜ˆμƒλ˜λ©΄ μ„œλ²„κ°€ μ„Ήμ…˜ 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. μ„Ήμ…˜ 객체λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ μ„Ήμ…˜ 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” 포인터와 크기에 κ΄€ν•œ 정보λ₯Ό λ‹΄κ³  μžˆλŠ” μž‘μ€ λ©”μ‹œμ§€κ°€ μ „μ†‘λ©λ‹ˆλ‹€. 이 방법은 μœ„μ—μ„œ λ‚˜μ—΄ν•œ 첫 번째 방법보닀 λ³΅μž‘ν•˜μ§€λ§Œ 데이터 볡사가 λ°œμƒν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. Windows의 κ³ κΈ‰ 지역 ν”„λ‘œμ‹œμ € 호좜의 ꡬ쑰가 μ•„λž˜ 이미지에 λ‚˜μ™€ μžˆμŠ΅λ‹ˆλ‹€.

Windows의 κ³ κΈ‰ 둜컬 ν”„λ‘œμ‹œμ € 호좜

 Windows의 κ³ κΈ‰ 둜컬 ν”„λ‘œμ‹œμ € 호좜 μ„€λΉ„λŠ” Windows API의 뢀뢄이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— μ‘μš© ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” μ‚¬μš©ν•  수 μ—†λ‹€λŠ” 사싀에 μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. Windows APIλ₯Ό μ‚¬μš©ν•˜λŠ” μ‘μš©μ€ ν‘œμ€€ 원격 ν”„λ‘œμ‹œμ € ν˜ΈμΆœμ„ λΆ€λ¦…λ‹ˆλ‹€. 같은 μ‹œμŠ€ν…œμƒμ— μ‘΄μž¬ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€μ˜ RPCκ°€ 호좜되면 이 RPCλŠ” κ°„μ ‘μ μœΌλ‘œ κ³ κΈ‰ 둜컬 ν”„λ‘œμ‹œμ € ν˜ΈμΆœμ„ ν†΅ν•˜μ—¬ μ²˜λ¦¬λ©λ‹ˆλ‹€. λ˜ν•œ λ§Žμ€ 컀널 μ„œλΉ„μŠ€λ“€μ€ ν΄λΌμ΄μ–ΈνŠΈ ν”„λ‘œμ„ΈμŠ€μ™€ ν†΅μ‹ ν•˜κΈ° μœ„ν•˜μ—¬ ALPCλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

 

 

4. νŒŒμ΄ν”„(Pipes)

νŒŒμ΄ν”„λŠ” 두 ν”„λ‘œμ„ΈμŠ€κ°€ 톡신할 수 있게 ν•˜λŠ” μ „λ‹¬μžλ‘œμ„œ λ™μž‘ν•©λ‹ˆλ‹€. νŒŒμ΄ν”„λŠ” 초기 UNIX μ‹œμŠ€ν…œμ—μ„œ μ œκ³΅ν•˜λŠ” IPC κΈ°λ²•μ˜ ν•˜λ‚˜μ˜€μŠ΅λ‹ˆλ‹€. νŒŒμ΄ν”„λŠ” 톡상 ν”„λ‘œμ„ΈμŠ€ 간에 ν†΅μ‹ ν•˜λŠ” 더 κ°„λ‹¨ν•œ λ°©λ²•μ˜ ν•˜λ‚˜μ΄μ§€λ§Œ 톡신할 λ•Œ μ—¬λŸ¬ μ œμ•½μ„ ν•©λ‹ˆλ‹€. νŒŒμ΄ν”„λ₯Ό κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ‹€μŒ 4가지 문제λ₯Ό κ³ λ €ν•΄μ•Ό ν•©λ‹ˆλ‹€.

  1. νŒŒμ΄ν”„κ°€ 단방ν–₯ 톡신 λ˜λŠ” μ–‘λ°©ν–₯ 톡신을 ν—ˆμš©ν•˜λŠ”κ°€?
  2. μ–‘λ°©ν–₯ 톡신이 ν—ˆμš©λœλ‹€λ©΄ λ°˜μ΄μ€‘(half duplex) 방식인가, 전이쀑(full duplex) 방식인가? λ°˜μ΄μ€‘ 박식은 ν•œμˆœκ°„μ— ν•œ λ°©ν–₯ μ „μ†‘λ§Œ κ°€λŠ₯ν•˜κ³  전이쀑 방식은 λ™μ‹œμ— μ–‘λ°©ν–₯ 데이터 전솑이 κ°€λŠ₯ν•˜λ‹€.
  3. ν†΅μ‹ ν•˜λŠ” 두 ν”„λ‘œμ„ΈμŠ€ 간에 λΆ€λͺ¨-μžμ‹κ³Ό 같은 νŠΉμ • 관계가 μ‘΄μž¬ν•΄μ•Όλ§Œ ν•˜λŠ”κ°€?
  4. νŒŒμ΄ν”„λŠ” λ„€νŠΈμ›Œν¬λ₯Ό ν†΅ν•˜μ—¬ 톡신이 κ°€λŠ₯ν•œκ°€, μ•„λ‹ˆλ©΄ λ™μΌν•œ 기계 μ•ˆμ— μ‘΄μž¬ν•˜λŠ” 두 ν”„λ‘œμ„ΈμŠ€λΌλ¦¬λ§Œ 톡신할 수 μžˆλŠ”κ°€?

μ•„λž˜μ—μ„œ UNIX와 Windows μ‹œμŠ€ν…œμ—μ„œ μ‚¬μš©λ˜λŠ” 일반 νŒŒμ΄ν”„μ™€ 지λͺ… νŒŒμ΄ν”„μ˜ 두 가지 μœ ν˜•μ˜ νŒŒμ΄ν”„μ— λŒ€ν•΄ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

(1) 일반 νŒŒμ΄ν”„(Ordinary Pipes)

일반 νŒŒμ΄ν”„λŠ” μƒμ‚°μž-μ†ŒλΉ„μž ν˜•νƒœλ‘œ 두 ν”„λ‘œμ„ΈμŠ€ κ°„μ˜ 톡신을 ν—ˆμš©ν•©λ‹ˆλ‹€. μƒμ‚°μžλŠ” νŒŒμ΄ν”„μ˜ ν•œ 쒅단(μ“°κΈ° 쒅단)에 μ“°κ³ , μ†ŒλΉ„μžλŠ” λ‹€λ₯Έ 쒅단(읽기 쒅단)μ—μ„œ μ½μŠ΅λ‹ˆλ‹€. 결과적으둜 일반 νŒŒμ΄ν”„λŠ” ν•œμͺ½μœΌλ‘œλ§Œ 데이터λ₯Ό 전솑할 수 있으며 였직 단방ν–₯ ν†΅μ‹ λ§Œμ„ κ°€λŠ₯ν•˜κ²Œ ν•©λ‹ˆλ‹€. 만일 μ–‘λ°©ν–₯ 톡신이 ν•„μš”ν•˜λ‹€λ©΄ 각각 λ‹€λ₯Έ λ°©ν–₯으둜 데이터λ₯Ό 전솑할 수 μžˆλŠ” 두 개의 νŒŒμ΄ν”„λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€. λ‹€μŒμœΌλ‘œ UNIX와 Windows μ‹œμŠ€ν…œμ—μ„œ 일반 νŒŒμ΄ν”„λ₯Ό κ΅¬μΆ•ν•˜λŠ” 예λ₯Ό μ„€λͺ…ν•©λ‹ˆλ‹€. 두 개의 ν”„λ‘œκ·Έλž¨ μ˜ˆμ œμ—μ„œ ν•œ ν”„λ‘œμ„ΈμŠ€λŠ” GreetingsλΌλŠ” λ©”μ‹œμ§€λ₯Ό νŒŒμ΄ν”„μ— μ“°κ³ , λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€λŠ” 이 λ©”μ‹œμ§€λ₯Ό νŒŒμ΄ν”„λ‘œλΆ€ν„° μ½μŠ΅λ‹ˆλ‹€. 

 UNIX μ‹œμŠ€ν…œμ—μ„œ 일반 νŒŒμ΄ν”„λŠ” λ‹€μŒ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ κ΅¬μΆ•λ©λ‹ˆλ‹€.

pipe(int fd[])

이 ν•¨μˆ˜λŠ” fd[] 파일 μ„€λͺ…μžλ₯Ό 톡해 μ ‘κ·Όλ˜λŠ” νŒŒμ΄ν”„λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. fd[0]λŠ” νŒŒμ΄ν”„μ˜ 읽기 쒅단이고 fd[1]은 νŒŒμ΄ν”„μ˜ μ“°κΈ° μ’…λ‹¨μœΌλ‘œ λ™μž‘ν•©λ‹ˆλ‹€. UNIXλŠ” νŒŒμ΄ν”„λ₯Ό 파일의 νŠΉμˆ˜ν•œ μœ ν˜•μœΌλ‘œ μ·¨κΈ‰ν•©λ‹ˆλ‹€. λ”°λΌμ„œ νŒŒμ΄ν”„λŠ” 일반적인 read()와 write() μ‹œμŠ€ν…œ μ½œμ„ μ‚¬μš©ν•˜μ—¬ 접근될 수 μžˆμŠ΅λ‹ˆλ‹€. 

 μΌλ°˜ νŒŒμ΄ν”„λŠ” νŒŒμ΄ν”„λ₯Ό μƒμ„±ν•œ ν”„λ‘œμ„ΈμŠ€ μ΄μ™Έμ—λŠ” μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ 톡산 λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€κ°€ νŒŒμ΄ν”„λ₯Ό μƒμ„±ν•˜κ³  fork()둜 μƒμ„±ν•œ μžμ‹ ν”„λ‘œμ„ΈμŠ€μ™€ ν†΅μ‹ ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•©λ‹ˆλ‹€. νŒŒμ΄ν”„λŠ” 파일의 νŠΉμˆ˜ν•œ μœ ν˜•μ΄κΈ° λ•Œλ¬Έμ— μžμ‹ ν”„λ‘œμ„ΈμŠ€λŠ” λΆ€λͺ¨λ‘œλΆ€ν„° νŒŒμ΄ν”„λ₯Ό μƒμ†λ°›μŠ΅λ‹ˆλ‹€. μ•„λž˜ μ΄λ―Έμ§€λŠ” fd λ°°μ—΄μ˜ 파일 λ””μŠ€ν¬λ¦½ν„°μ™€ λΆ€λͺ¨ 및 μžμ‹ ν”„λ‘œμ„ΈμŠ€μ˜ 관계λ₯Ό λ³΄μ—¬μ€λ‹ˆλ‹€. 

일반 νŒŒμ΄ν”„λ₯Ό μœ„ν•œ 파일 λ””μŠ€ν¬λ¦½ν„°

μœ„ μ΄λ―Έμ§€μ—μ„œ 보듯이 λΆ€λͺ¨κ°€ νŒŒμ΄ν”„μ˜ μ“°κΈ° 쒅단(fd[1])에 데이터λ₯Ό μ“°λ©΄ νŒŒμ΄ν”„μ˜ 읽기 쒅단(fd[0])μ—μ„œ μžμ‹μ΄ 읽을 수 μžˆμŠ΅λ‹ˆλ‹€.

UNIX의 일반 νŒŒμ΄ν”„

#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define BUFFER SIZE 25
#define READ END 0
#define WRITE END 1

int main(void)
{
    char write msg[BUFFER SIZE] = "Greetings";
    char read msg[BUFFER SIZE];
    int fd[2];
    pid t pid;
    
    /* create the pipe */
    if (pipe(fd) == -1) {
        fprintf(stderr,"Pipe failed");
        return 1;
    }
    
    /* fork a child process */
    pid = fork();
    
    if (pid < 0) { /* error occurred */
        fprintf(stderr, "Fork Failed");
        return 1;
    }
    
    if (pid > 0) { /* parent process */
        /* close the unused end of the pipe */
        close(fd[READ END]);
        
        /* write to the pipe */
        write(fd[WRITE END], write msg, strlen(write msg)+1);
        
        /* close the write end of the pipe */
        close(fd[WRITE END]);
    }
    else { /* child process */
        /* close the unused end of the pipe */
        close(fd[WRITE END]);
        
        /* read from the pipe */
        read(fd[READ END], read msg, BUFFER SIZE);
        printf("read %s",read msg);
        
        /* close the read end of the pipe */
        close(fd[READ END]);
    }
    
    return 0;
}

 

μœ„ μ½”λ“œμ—μ„œ 보인 UNIX ν”„λ‘œκ·Έλž¨μ—μ„œ λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€λŠ” νŒŒμ΄ν”„λ₯Ό μƒμ„±ν•˜κ³  μžμ‹ ν”„λ‘œμ„ΈμŠ€λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•˜μ—¬ fork()λ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€. fork() 후에 μΌμ–΄λ‚˜λŠ” μž‘μ—…μ€ νŒŒμ΄ν”„λ₯Ό 톡해 데이터가 μ–΄λ–»κ²Œ ν˜λŸ¬κ°€λŠλƒμ— 따라 λ‹¬λΌμ§‘λ‹ˆλ‹€. 이 μ˜ˆμ œμ—μ„œλŠ” λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€κ°€ νŒŒμ΄ν”„μ— μ“°κ³ , μžμ‹ ν”„λ‘œμ„ΈμŠ€κ°€ νŒŒμ΄ν”„λ‘œλΆ€ν„° μ½μŠ΅λ‹ˆλ‹€. λΆ€λͺ¨μ™€ μžμ‹ ν”„λ‘œμ„ΈμŠ€ λͺ¨λ‘ μ²˜μŒμ— μžμ‹ λ“€μ΄ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” νŒŒμ΄ν”„μ˜ 쒅단을 λ‹«λŠ” 것을 μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. μœ„ μ½”λ“œμ— 보인 ν”„λ‘œκ·Έλž¨μ€ μ΄λŸ¬ν•œ μž‘μ—…μ„ ν•˜μ§€λŠ” μ•Šμ§€λ§Œ writerκ°€ νŒŒμ΄ν”„μ˜ 쒅단을 λ‹«μ•˜μ„ λ•Œ, νŒŒμ΄ν”„λ‘œλΆ€ν„° μ½λŠ” ν”„λ‘œμ„ΈμŠ€κ°€ end-of-file (reade()κ°€ 0을 λ°˜ν™˜)을 νƒμ§€ν•˜λŠ” 것을 보μž₯ν•˜κΈ° λ•Œλ¬Έμ— 이 μž‘μ—…μ€ 맀우 μ€‘μš”ν•œ μ ˆμ°¨μž…λ‹ˆλ‹€.

 Windows μ‹œμŠ€ν…œμ˜ 일반 νŒŒμ΄ν”„λŠ” 읡λͺ… νŒŒμ΄ν”„(anonynous pipe)라고 뢈리며 UNIX의 λŒ€μ‘λ˜λŠ” νŒŒμ΄ν”„μ™€ μœ μ‚¬ν•˜κ²Œ λ™μž‘ν•©λ‹ˆλ‹€. 이 νŒŒμ΄ν”„λŠ” 단방ν–₯이고 ν†΅μ‹ ν•˜λŠ” 두 ν”„λ‘œμ„ΈμŠ€λŠ” λΆ€λͺ¨-μžμ‹ 관계여야 ν•©λ‹ˆλ‹€. κ²Œλ‹€κ°€ νŒŒμ΄ν”„μ˜ 읽기와 μ“°κΈ°λŠ” λ³΄ν†΅μ˜ Read-File()κ³Ό WriteFile()을 μ‚¬μš©ν•˜μ—¬ μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€. νŒŒμ΄ν”„λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•œ Windows APIλŠ” CreatePipe() ν•¨μˆ˜λ‘œμ„œ 5개의 λ§€κ°œλ³€μˆ˜λ₯Ό μ „λ‹¬λ°›μŠ΅λ‹ˆλ‹€. λ§€κ°œλ³€μˆ˜λŠ” (1) 읽기, (2) μ“°κΈ°, (3) μžμ‹ ν”„λ‘œμ„ΈμŠ€κ°€ νŒŒμ΄ν”„μ˜ 핸듀을 μƒμ†λ°›λŠ”λ‹€λŠ” 것을 λͺ…μ‹œν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” STARTUPINFO ꡬ쑰체의 μΈμŠ€ν„΄μŠ€λ₯Ό μœ„ν•œ 각각의 핸듀을 μ „λ‹¬λ°›μŠ΅λ‹ˆλ‹€. 그리고 (4) λ°”μ΄νŠΈ λ‹¨μœ„μ˜ νŒŒμ΄ν”„μ˜ 크기가 지정될 수 μžˆμŠ΅λ‹ˆλ‹€.

Windows 읡λͺ… νŒŒμ΄ν”„-λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define BUFFER SIZE 25

int main(VOID){
    HANDLE ReadHandle, WriteHandle;
    STARTUPINFO si;
    PROCESS INFORMATION pi;
    char message[BUFFER SIZE] = "Greetings";
    DWORD written;
    
    /* set up security attributes allowing pipes to be inherited */
    SECURITY ATTRIBUTES sa = {sizeof(SECURITY ATTRIBUTES),NULL,TRUE};
    /* allocate memory */
    ZeroMemory(&pi, sizeof(pi));
    
    /* create the pipe */
    if (!CreatePipe(&ReadHandle, &WriteHandle, &sa, 0)) {
        fprintf(stderr, "Create Pipe Failed");
        return 1;
    }
    
    /* establish the START INFO structure for the child process */
    GetStartupInfo(&si);
    si.hStdOutput = GetStdHandle(STD OUTPUT HANDLE);
    
    /* redirect standard input to the read end of the pipe */
    si.hStdInput = ReadHandle;
    si.dwFlags = STARTF USESTDHANDLES;
    
    /* don’t allow the child to inherit the write end of pipe */
    SetHandleInformation(WriteHandle, HANDLE FLAG INHERIT, 0);
    
    /* create the child process */
    CreateProcess(NULL, "child.exe", NULL, NULL,
                  TRUE, /* inherit handles */
                  0, NULL, NULL, &si, &pi);
    
    /* close the unused end of the pipe */
    CloseHandle(ReadHandle);
    
    /* the parent writes to the pipe */
    if (!WriteFile(WriteHandle, message,BUFFER SIZE,&written,NULL))
        fprintf(stderr, "Error writing to pipe.");
    
    /* close the write end of the pipe */
    CloseHandle(WriteHandle);
    
    /* wait for the child to exit */
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return 0;
}

μœ„ μ½”λ“œλŠ” μžμ‹ ν”„λ‘œμ„ΈμŠ€μ™€ ν†΅μ‹ ν•˜κΈ° μœ„ν•˜μ—¬ 읡λͺ… νŒŒμ΄ν”„λ₯Ό μƒμ„±ν•˜λŠ” λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ„€λͺ…ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μžμ‹ ν”„λ‘œμ„ΈμŠ€κ°€ λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€κ°€ μƒμ„±ν•œ νŒŒμ΄ν”„λ₯Ό μžλ™μœΌλ‘œ μƒμ†λ°›λŠ” UNIX μ‹œμŠ€ν…œκ³ΌλŠ” λ‹€λ₯΄κ²Œ Windowsμ—μ„œλŠ” ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μ–΄λ–€ 속성을 μƒμ†λ°›λŠ”μ§€λ₯Ό λͺ…μ‹œν•΄μ•Ό ν•©λ‹ˆλ‹€. μš°μ„  핸듀을 상속받을 수 μžˆλ„λ‘ SECURITY_ATTRIBUTES ꡬ쑰λ₯Ό μ΄ˆκΈ°ν™”ν•˜κ³  λ‹€μŒμ— μžμ‹ ν”„λ‘œμ„ΈμŠ€μ˜ ν‘œμ€€ μž…λ ₯ λ˜λŠ” ν‘œμ€€ 좜λ ₯ 핸듀을 νŒŒμ΄ν”„μ˜ 읽기 λ˜λŠ” μ“°κΈ° ν•Έλ“€λ‘œ μž¬μ§€μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€. μžμ‹ ν”„λ‘œμ„ΈμŠ€κ°€ νŒŒμ΄ν”„λ‘œλΆ€ν„° 읽도둝 λ§Œλ“€μ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— λΆ€λͺ¨ ν”„λ‘œμ„ΈμŠ€λŠ” μžμ‹μ˜ ν‘œμ€€ μž…λ ₯을 νŒŒμ΄ν”„μ˜ 읽기 ν•Έλ“€λ‘œ μž¬μ§€μ •ν•΄μ•Όλ§Œ ν•©λ‹ˆλ‹€. λ”μš±μ΄ νŒŒμ΄ν”„λŠ” λ°˜μ΄μ€‘ λ°©μ‹μ΄λ―€λ‘œ μžμ‹μ΄ νŒŒμ΄ν”„μ˜ μ“°κΈ° 쒅단을 μƒμ†λ°›λŠ” 것을 κΈˆμ§€μ‹œμΌœμ•Ό ν•©λ‹ˆλ‹€. νŒŒμ΄ν”„μ— μ“°κΈ° 전에 λΆ€λͺ¨λŠ” λ¨Όμ € νŒŒμ΄ν”„μ˜ μ‚¬μš©ν•˜μ§€ μ•Šμ„ 읽기 쒅단을 λ‹«μŠ΅λ‹ˆλ‹€. νŒŒμ΄ν”„λ‘œλΆ€ν„° μ½λŠ” μžμ‹ ν”„λ‘œμ„ΈμŠ€λŠ” μ•„λž˜μ˜ μ½”λ“œμ— λ‚˜μ™€ μžˆμŠ΅λ‹ˆλ‹€. νŒŒμ΄ν”„λ‘œλΆ€ν„° 읽기 전에 이 ν”„λ‘œκ·Έλž¨μ€ GetStdHandle() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ νŒŒμ΄ν”„μ˜ 읽기 핸듀을 νšλ“ν•©λ‹ˆλ‹€.

Windows 읡λͺ… νŒŒμ΄ν”„-μžμ‹ ν”„λ‘œμ„ΈμŠ€

#include <stdio.h>
#include <windows.h>
#define BUFFER SIZE 25

int main(VOID)
{
    HANDLE Readhandle;
    CHAR buffer[BUFFER SIZE]; DWORD read;
    
    /* get the read handle of the pipe */
    ReadHandle = GetStdHandle(STD INPUT HANDLE);
    
    /* the child reads from the pipe */
    if (ReadFile(ReadHandle, buffer, BUFFER SIZE, &read, NULL))
        printf("child read %s",buffer);
    else
        fprintf(stderr, "Error reading from pipe");
    
    return 0;
}

 UNIX와 Windows μ‹œμŠ€ν…œ λͺ¨λ‘μ—μ„œ ν†΅μ‹ ν•˜λŠ” 두 ν”„λ‘œμ„ΈμŠ€λŠ” λΆ€λͺ¨-μžμ‹ 관계λ₯Ό κ°€μ Έμ•Ό ν•œλ‹€λŠ” 것을 λͺ…μ‹¬ν•˜μ—¬μ•Ό ν•©λ‹ˆλ‹€. 이 μœ ν˜•μ˜ νŒŒμ΄ν”„λŠ” λ™μΌν•œ κΈ°κ³„μƒμ˜ 두 ν”„λ‘œμ„ΈμŠ€λΌλ¦¬λ§Œ 톡신이 κ°€λŠ₯ν•˜λ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.

(2) 지λͺ… νŒŒμ΄ν”„(Named Pipes)

일반 νŒŒμ΄ν”„λŠ” ν•œ 쌍의 ν”„λ‘œμ„ΈμŠ€κ°€ 톡신할 수 μžˆλŠ” κ°„λ‹¨ν•œ 기법을 μ œκ³΅ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 일반 νŒŒμ΄ν”„λŠ” μ˜€λ‘œμ§€ ν”„λ‘œμ„ΈμŠ€λ“€μ΄ μ„œλ‘œ ν†΅μ‹ ν•˜λŠ” λ™μ•ˆμ—λ§Œ μ‘΄μž¬ν•©λ‹ˆλ‹€. UNIX와 Windowsμ‹œμŠ€ν…œ λͺ¨λ‘μ—μ„œ ν”„λ‘œμ„ΈμŠ€λ“€μ΄ 톡신을 마치고 μ’…λ£Œν•˜λ©΄ 일반 νŒŒμ΄ν”„λŠ” μ—†μ–΄μ§€κ²Œ λ©λ‹ˆλ‹€.

 μ§€λͺ… νŒŒμ΄ν”„(named pipes)λŠ” μ’€ 더 κ°•λ ₯ν•œ 톡신 도ꡬλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€. 톡신은 μ–‘λ°©ν–₯으둜 κ°€λŠ₯ν•˜λ©° λΆ€λͺ¨-μžμ‹ 관계도 ν•„μš”λ‘œ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 지λͺ… νŒŒμ΄ν”„κ°€ κ΅¬μΆ•λ˜λ©΄ μ—¬λŸ¬ ν”„λ‘œμ„ΈμŠ€λ“€μ΄ 이λ₯Ό μ‚¬μš©ν•˜μ—¬ 톡신할 수 μžˆμŠ΅λ‹ˆλ‹€. μ‹€μ œ ν†΅μƒμ˜ μ‹œλ‚˜λ¦¬μ˜€μ—μ„œ 지λͺ… νŒŒμ΄ν”„λŠ” λ‹€μˆ˜μ˜ writerλ₯Ό κ°€μ§‘λ‹ˆλ‹€. μΆ”κ°€λ‘œ 톡신 ν”„λ‘œμ„ΈμŠ€κ°€ μ’…λ£Œν•˜λ”λΌλ„ 지λͺ… νŒŒμ΄ν”„λŠ” 계속 μ‘΄μž¬ν•˜κ²Œ λ©λ‹ˆλ‹€. UNIX와 Windows μ‹œμŠ€ν…œμ€ κ΅¬ν˜„μƒμ— 차이점은 μžˆμ§€λ§Œ λͺ¨λ‘ 지λͺ… νŒŒμ΄ν”„λ₯Ό μ§€μ›ν•©λ‹ˆλ‹€. λ‹€μŒμœΌλ‘œ 각 μ‹œμŠ€ν…œμ˜ 지λͺ… νŒŒμ΄ν”„λ₯Ό μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 μ§€λͺ… νŒŒμ΄ν”„λ₯Ό UNIXμ—μ„œλŠ” FIFO라고 λΆ€λ¦…λ‹ˆλ‹€. μƒμ„±λ˜λ©΄ 지λͺ… νŒŒμ΄ν”„λŠ” 파일 μ‹œμŠ€ν…œμ˜ 보톡 파일처럼 μ‘΄μž¬ν•©λ‹ˆλ‹€. FIFOλŠ” mkfifo() μ‹œμŠ€ν…œ μ½œμ„ μ΄μš©ν•˜μ—¬ μƒμ„±λ˜κ³  일반적인 open(), read(), write(), 및 close() μ‹œμŠ€ν…œ 콜둜 μ‘°μž‘λ©λ‹ˆλ‹€. λͺ…μ‹œμ μœΌλ‘œ 파일 μ‹œμŠ€ν…œμ—μ„œ μ‚­μ œλ  λ•ŒκΉŒμ§€ μ‘΄μž¬ν•˜κ²Œ λ©λ‹ˆλ‹€. FIFOκ°€ μ–‘λ°©ν–₯ 톡신을 ν—ˆμš©ν•˜κΈ°λŠ” ν•˜μ§€λ§Œ λ°˜μ΄μ€‘ μ „μ†‘λ§Œμ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€. 데이터가 μ–‘λ°©ν–₯으둜 전솑될 ν•„μš”κ°€ μžˆλ‹€λ©΄, 보톡 2개의 FIFOκ°€ μ‚¬μš©λ©λ‹ˆλ‹€. λΆ€κ°€μ μœΌλ‘œ ν†΅μ‹ ν•˜λŠ” 두 ν”„λ‘œμ„ΈμŠ€λŠ” λ™μΌν•œ 기계 내에 μ‘΄μž¬ν•΄μ•Ό ν•©λ‹ˆλ‹€. μ„œλ‘œ λ‹€λ₯Έ 기계에 μ‘΄μž¬ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€ 사이에 톡신이 ν•„μš”ν•˜λ‹€λ©΄ μ†ŒμΌ“μ„ μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

 Windows μ‹œμŠ€ν…œμ˜ 지λͺ… νŒŒμ΄ν”„λŠ” UNIX의 상응 νŒŒμ΄ν”„λ³΄λ‹€ 훨씬 ν’λΆ€ν•œ 톡신 기법을 μ œκ³΅ν•©λ‹ˆλ‹€. 전이쀑 톡신을 ν—ˆμš©ν•˜λ©°, ν†΅μ‹ ν•˜λŠ” 두 ν”„λ‘œμ„ΈμŠ€λŠ” 같은 기계 λ˜λŠ” λ‹€λ₯Έ 기계상에 μ‘΄μž¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μΆ”κ°€λ‘œ UNIX FIFOκ°€ λ°”μ΄νŠΈ-λ‹¨μœ„ ν†΅μ‹ λ§Œμ„ ν—ˆμš©ν•˜λŠ” 것과 비ꡐ해 Windows μ‹œμŠ€ν…œ νŒŒμ΄ν”„λŠ” λ°”μ΄νŠΈ-λ‹¨μœ„ λ˜λŠ” λ©”μ‹œμ§€-λ‹¨μœ„ λ°μ΄ν„°μ˜ 전솑을 ν—ˆμš©ν•©λ‹ˆλ‹€. 지λͺ… νŒŒμ΄ν”„λŠ” CreateNamePipe() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μƒμ„±λ˜κ³  ν΄λΌμ΄μ–ΈνŠΈλŠ” ConnectNamedPipe() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 지λͺ… νŒŒμ΄ν”„μ— μ—°κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 지λͺ… νŒŒμ΄ν”„λ₯Ό ν†΅ν•œ 톡신은 ReadFile()κ³Ό WriteFile() ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ‹€ν–‰λ©λ‹ˆλ‹€.

 

 

λŒ“κΈ€