1 Program != 1 Process


1 Program == n Process


하나의 프로그램을 이루기 위해 n개의 프로세스가 서로 데이터 통신을 해야하는 경우가 종종 있다.


이 때, 프로세스간 통신이 원활히 이루어져야 좋은 프로그램이 될 것



프로세스의 메모리는 안정성을 이유로 OS에 의해 분리되어있다. (고립되어있다.)


그렇기 때문에 프로세스간 공유할 메모리 공간을 확보해야하는데, 그러한 공간을 OS가 또한 제공해준다.


이러한 기법을 Inner Process Communication, IPC라 부른다.


프로세스간 통신

프로세스간 데이터 송수신 -> 메모리 공유


-> 데이터를 순차적으로 보내는 것이 아니라, A프로세스가 공유가 가능한 어떠한 메모리 공간을 생성, B프로세스는 그곳에 보낼 데이터를 집어넣는다.

A프로세스는 생성한 메모리 공간을 확인, 데이터가 있으면 데이터를 받아온다.



메일슬롯


IPC 데이터 통신 기법의 하나. Receiver는 데이터를 받을 수 있는 우체통을 만들기 위해 함수를 호출한다. OS는 그러한 함수 호출을 통해 Receiver와 Sender가 접근 가능한 메모리 공간을 마련한다.


Receiver가 "서울 100번지"라는 이름의 주소를 설정해 OS에 요청하면, 주소를 알고 있는 Sender가 주소에 데이터를 붙여서 전송하면 OS가 그것을 보고 해당 주소에 보낸다.


핵심 함수는 우체통 생성, 전송, 송신의 3가지 함수다.(추가적으로 하나 더 있다.)


여기서 중요한 점은 이러한 방식의 기법이 단방향이라는 것이다. 


일반적으로 통신은 양방향이지만, 이러한 우체통의 송수신 방식은 단방향이기때문에 Sender는 데이터를 보낼수는 있지만, 받을수는 없다.


또한 n개의 Receiver가 동일한 주소의 우체통을 생성할수도 있다. 이 경우 Sender가 해당 주소로 데이터를 전송할 때 한번에 각각 Receiver가 데이터를 받을 수 있다. 


이를 브로드캐스팅이라고 한다.



Receiver


CreateMailSlot

우체통을 만든다


Sender


CreateFile

우체통과의 길을 뚫는다.


밑의 OX는 단방향 통신의 특성을 보여준다.


왜 송수신을 하는데 함수 이름이 File인가?


근본적으로 메일슬롯 방식은 메모리 공유다. 파일 기반으로 구현이 되어 있어서 기존 함수를 사용하는 것이다.


다른 의미로는 파일 기반으로 구현되어 있다는 것을 노출한 것이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
        MailReceiver.cpp
*/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#define SLOT_NAME    _T("\\\\.\\mailslot\\mailbox")
int _tmain(int argc, LPTSTR argv[])
{
    HANDLE hMailSlot;  //mailslot 핸들
    TCHAR messageBox[50];
    DWORD bytesRead;  // number of bytes read
          /* mailslot 생성*/
    hMailSlot = CreateMailslot(SLOT_NAME, 0, MAILSLOT_WAIT_FOREVER, NULL);
    if (hMailSlot == INVALID_HANDLE_VALUE)
    {
        _fputts(_T("Unable to create mailslot!\n"), stdout);
        return 1;
    }
    /* Message 수신*/
    _fputts(_T("******** Message ********\n"), stdout);
    while (1)
    {
        if (!ReadFile(hMailSlot, messageBox, sizeof(TCHAR) * 50&bytesRead, NULL))
        {
            _fputts(_T("Unable to read!"), stdout);
            CloseHandle(hMailSlot);
            return 1;
        }
        if (!_tcsncmp(messageBox, _T("exit"), 4))
        {
            _fputts(_T("Good Bye!"), stdout);
            break;
        }
        messageBox[bytesRead / sizeof(TCHAR)] = 0//NULL 문자 삽입
        _fputts(messageBox, stdout);
    }
    CloseHandle(hMailSlot);
    return 0;
}
cs


7 : .의 위치에는 컴퓨터 이름을 넣어야 한다. .의 의미는 나 자신을 의미한다. Receiver는 사용자 컴퓨터에서 실행하기 때문에 .밖에 올 수 없다. 나 자신의 위치에 데이터를 받아야지


14 : 두번째 인자는 버퍼 크기를 의미한다. 0은 허용최대치

세번째 인자는 데이터가 우체통에 들어올때까지 계속 기다릴것인지를 묻는 옵션이다. 이 경우 Blocked 상태가 되는 것


24 : ReadFile의 첫번째 인자는 슬롯을 지정하는 것이다. hMailSlot로 CreateMailSlot함수를 호출하면 슬롯이 생성되면서 슬롯의 핸들이 반환된다. 그 핸들을 넣어 Read의 대상(슬롯)을 지정한다

두번째 인자는 읽은 데이터를 저장할 버퍼를 의미한다

세번째 인자는 읽는 데이터의 최대 크기를 의미한다

네번째 인자는 실제로 읽은 데이터 크기를 얻기 위해 존재한다.

다섯번째 인자는 보류


38 : 커널오브젝트의 소멸을 돕기 위해 UC를 내리기 위한 CloseHandle 함수다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
        MailSender.cpp
*/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#define SLOT_NAME _T("\\\\.\\mailslot\\mailbox")
int _tmain(int argc, LPTSTR argv[])
{
    HANDLE hMailSlot;  //mailslot 핸들
    TCHAR message[50];
    DWORD bytesWritten;  // number of bytes write
    hMailSlot = CreateFile(SLOT_NAME, GENERIC_WRITE, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hMailSlot == INVALID_HANDLE_VALUE)
    {
        _fputts(_T("Unable to create mailslot!\n"), stdout);
        return 1;
    }
    while (1)
    {
        _fputts(_T("MY CMD>"), stdout);
        _fgetts(message, sizeof(message) / sizeof(TCHAR), stdin);
        if (!WriteFile(hMailSlot, message, _tcslen(message) * sizeof(TCHAR), &bytesWritten, NULL))
        {
            _fputts(_T("Unable to write!"), stdout);
            CloseHandle(hMailSlot);
            return 1;
        }
        if (!_tcscmp(message, _T("exit")))
        {
            _fputts(_T("Good Bye!"), stdout);
            break;
        }
    }
    CloseHandle(hMailSlot);
    return 0;
}
cs


7 : 같은 컴퓨터기때문에 .이 찍혀야한다. 이게 왜 있냐면 네트워크로 연결되어 있는 서로 다른 컴퓨터에서도 사용이 가능하다. 

근데, TCP/IP를 사용하는것이 일반적이다. 이거 잘 안씀


13 : 첫번째 인자는 연결 슬롯의 이름이다

두번째 인자는 Read인지, Write인지를 결정하는 옵션이다.

다섯번째 인자는 생성 방식을 의미한다. OPEN_EXISTING은 새로 만들것인지, 존재하는 것을 연결할 것인지 뭐 그런것

Sender의 CreateFile은 그 인자가 대체로 고정되어있는 편이다. 일단 읽고 넘어가라고함


24 : 첫번째 인자는 주소정보를 지정하는 것이다

두번째 인자는 전송 데이터를 담은 버퍼다

세번째 인자는 최대 전송 데이터 크기다

네번째 인자는 전송 결과를 의미한다.

다섯번째는 보류


36 : 클로즈핸들ㅇㅇ



결과 

왼쪽은 Sender

오른쪽은 Receiver


마치 소켓통신같군


추가할거더잇음 함수좀더봐야함

'운영체제 > 윈도우 시스템' 카테고리의 다른 글

프로세스간 통신(IPC)2  (0) 2019.10.01
Signaled Non-Signaled  (0) 2019.09.27
커널 오브젝트, 핸들의 종속관계  (0) 2019.09.26
커널 오브젝트 오브젝트 핸들  (0) 2019.09.26
프로세스, 스케줄러  (0) 2019.09.25

+ Recent posts