728x90

 

프로세스 간 통신(IPC)

- 독립된 프로세스 간 데이터를 주고 받음 => 메모리를 공유함

    -> 공유되는 메모리 공간안에 프로세스가 데이터를 가져다 놓고 가져가게 됨

- 프로세스 메모리 영역은 OS에 의해 분리되어 있음

    -> 다른 프로그램의 영향을 미치는 것을 방지하기 위함(안전성)

- 하나의 프로그램 안에 여러 프로세스를 구성할 때 중요

메일슬롯 방식의 IPC

- 메일 슬롯 : 우체통의 의미를 가지는 송수신 프로세스가 공유하는 메모리 영역

- 동작 원리

    -> 수신측의 프로세스가 간접적으로 호출이 가능한 우체통을 하나 만들고 주소를 부여

    -> 송신측의 프로세스는 우체통의 주소를 통해 데이터를 전송함

    -> 수신측에서 우체통을 확인하고 데이터가 있다면 데이터를 가져감 

- 특징

    -> 단방향 통신 : 송신측은 송신만 수신측은 수신만 가능함

    -> 송신측의 프로세스는 수신측에 동일한 주소의 우체통이 있다면 한번에 각각의 수신 프로세스에 데이터를 보내주게 됨(Broadcast)

- 예제

// mailreceive.cpp

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

#define SLOT_NAME _T("\\\\.\\mailslot\\mailbox")	// 계층적 구조('.' 자리는 컴퓨터 이름 '.' 은 자기 자신)

int _tmain(int argc, TCHAR* argv[])
{
	HANDLE hMailSlot;	// mailslot 핸들
	TCHAR messageBox[50];
	DWORD bytesRead;

	hMailSlot = CreateMailslot(
		SLOT_NAME,					// 메일 슬롯 이름(주소)
		0,							// 메일 슬롯 버퍼 크기(0 = 최대치)
		MAILSLOT_WAIT_FOREVER, 
		NULL						// 보안 설정
	);

	if (hMailSlot == INVALID_HANDLE_VALUE)
	{
		_fputts(_T("Unable to create mailslot\n"), stdout);
		return 1;
	}
	_fputts(_T("**** Message ****"), 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;
		_fputts(messageBox, stdout);
	}
	CloseHandle(hMailSlot);			// 메일 슬롯 소멸
	return 0;
}
// mailsend.cpp

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

#define SLOT_NAME _T("\\\\.\\mailslot\\mailbox")	// 계층적 구조('.' 자리는 컴퓨터 이름 '.' 은 자기 자신)

int _tmain(int argc, TCHAR* argv[])
{
	HANDLE hMailSlot;	// mailslot 핸들
	TCHAR message[50];
	DWORD bytesWritten;

	hMailSlot = CreateFile(
		SLOT_NAME,					// 메일 슬롯 이름(주소)
		GENERIC_WRITE,				// 메일 슬롯 용도(sender는 무조건 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("Input Message >> "), stdout);
		_fgetts(message, sizeof(message) / sizeof(TCHAR), stdin);
		if (!WriteFile(
			hMailSlot,							// 메일 슬롯
			message,							// 전송할 데이터
			_tcslen(message)*sizeof(TCHAR),		// 전송할 데이터 크기
			&bytesWritten,						// 전송의 결과
			NULL
			)
			)
		{
			_fputts(_T("Unable to read"), stdout);
			CloseHandle(hMailSlot);
			return 1;
		}
		if (!_tcsncmp(message, _T("exit"), 4))
		{
			_fputts(_T("Good Bye"), stdout);
			break;
		}
	}
	CloseHandle(hMailSlot);			// 메일 슬롯 소멸
	return 0;
}

- 결과

    -> mailrecv 먼저 실행

    -> mailsend 실행 후 메시지 입력

    -> mailrecv 확인

    -> exit 전송 시

    -> 메일 슬롯이 생성되어 있지 않을 때 

728x90

+ Recent posts