커널이란
커널은 운영 체제의 핵심적인 부분으로서, 하드웨어와 소프트웨어 사이의 중재자 역할을 하며, 시스템 자원과 프로세스를 관리합니다
- 프로세스 관리: 프로그램이 어떻게, 언제 실행될지 결정
- 메모리 관리: 컴퓨터의 메모리를 효율적으로 할당하고 관리
- 디바이스 드라이버: 특정 하드웨어를 제어하는 방법을 알고 있어, 응용 프로그램이 해당 하드웨어를 사용할 수 있게 함
- 시스템 호출 및 인터럽트 처리: 사용자 프로그램이 커널의 기능을 요청하거나, 하드웨어에서 발생하는 중단 상황을 처리
- 파일 시스템 관리: 디스크에 저장된 파일의 생성, 삭제, 읽기, 쓰기 등을 관리
유저모드와 커널 모드의 이해
유저 모드(User Mode)
유저 모드는 일반적으로 우리가 흔히 사용하는 응용 프로그램(웹 브라우저, 텍스트 에디터, 게임 등)이 실행되는 모드입니다. 유저 모드에서 실행되는 프로그램은 직접적으로 하드웨어에 접근할 수 없는 대신 커널에게 요청을 보내어 필요한 서비스를 이용할 수 있습니다.
커널 모드(Kernel Mode)
커널 모드는 시스템의 핵심적인 작업을 수행하는 곳입니다. 커널 모드에서 실행되는 코드는 하드웨어 자원에 직접 접근할 수 있고, 메모리 관리, 프로세스 스케줄링, 입출력 관리 등 시스템의 기본적인 서비스를 수행합니다. 물론 이런 권한은 매우 강력하므로, 커널 모드에서 실행되는 코드는 신중하게 작성되고 테스트되어야 합니다. 그렇지 않으면, 시스템 전체에 치명적인 오류를 일으킬 수 있습니다.
유저 모드와 커널 모드의 전환
일반적으로 프로그램은 유저 모드에서 시작되고, 커널의 서비스가 필요할 때만 커널 모드로 전환되는데 이러한 전환을 '시스템 호출'이라고 합니다.
시스템 호출은 프로그램이 커널에게 서비스를 요청하는 방법입니다. 시스템 호출이 발생하면, 컴퓨터는 커널 모드로 전환하여 요청된 서비스를 수행하고, 작업이 완료되면 다시 유저 모드로 돌아갑니다.
유저 모드와 커널 모드의 구분하는 이유는 컴퓨터의 시스템이 안전하고 효율적으로 동작하도록 하기 위함이고, 이를 통해 필요한 작업을 수행하면서도 시스템을 보호할 수 있습니다.
유저 모드에서의 동기화
유저 모드 동기화의 장-단점
장점
- 커널 모드 동기화 기법에 비해 가볍고 빠르다.
- 사용 방법이 비교적 쉽다
단점
- 커널 모드에서의 동기화 기법에 비해서 제한된 기능만을 갖고있다.
(제한된 기능 ex) 단일 프로세스 내에서만 사용이 가능) - Deadlock에 빠지기 쉽다.
유저 모드 동기화 기법 종류
- CRITICAL_SECTION 오브젝트
CRITICAL_SECTION 오브젝트 관련 함수
초기화
#includ <windows.h>
void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
임계 영역에 들어가기 위한 CS 소유 호출 함수
#include <windows.h>
void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
임계 영역 빠져나오며 CS 반환 함수
#include <windows.h>
void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
CS 소멸 함수
#include <windows.h>
void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
커널 모드에서의 동기화
커널 모드 동기화의 장-단점
장점
- 유저 모드에 비해 Deadlock에 빠질 가능성이 더 적음
- 다중 프로세스에 존재하는 쓰레드들 간의 동기화 가능
단점
- 유저 모드에 비해 무겁고 느리다.
커널 모드 동기화 기법 종류
- Mutex
- Semaphore
- Event (이번 포스팅은 이벤트 제외)
Mutex
Mutex란 여러 스레드 또는 프로세스 사이에서 공유 자원에 대한 동시 접근을 제어하는 동기화 기법입니다. 즉, 하나의 스레드 또는 프로세스가 특정 공유 자원을 사용하고 있을 때, 다른 스레드 또는 프로세스는 그 자원을 사용할 수 없도록 하는 동기화 기법입니다.
Mutex(Mutex Exclusion) 관련 함수
Mutex 생성 함수
#include <windows.h>
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner,
LPCTSTR lpName
);
Mutex 소유 함수
#include <windows.h>
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
해당 함수는 다른 스레드가 특정 작업을 완료할 때까지 대기하거나, 공유 리소스에 대한 동기화를 관리하는 데 사용됩니다
Mutex를 반환하는 함수
#include <windows.>
BOOL ReleaseMutex(HANDLE hMutex);
Mutex를 소멸하는 함수(커널 오브젝트를 소멸하는 함수)
#include <windows.h>
BOOL CloseHandle(HANDLE hObject);
Mutex의 동작 방식
- A 쓰레드가 임계 영역을 진입하기 위해 WaitForSingleObject 호출
Mutex는 생성과 동시에 Signaled 상태기 때문에(CrateMutex 함수의 두 번째 인자에 FALSE인 경우) 바로 임계 영역 진입 이후 Mutex는 non-signaled상태가 된다. - B 쓰레드가 임계 영역에 진입하기 위해 WaitForSingleObject 호출 했지만 Mutex가 non-signaled 상태기 때문에 Mutex가 signaled 상태로 바뀔때 까지 대기 상태
- A 쓰레드가 임계 영역을 빠져나가면서 ReleaseMutex함수 호출
Mutex는 signaled상태가 되고 대기 중에 있던 B 쓰레드는 임계 영역에 진입을 할 수 있게 된다.
Semaphore
세마포어는 일반적으로 두 가지 유형으로 나눌 수 있습니다: 이진 세마포어(Binary Semaphore)와 계수 세마포어(Counting Semaphore).
- 이진 세마포어: 값이 0 또는 1인 세마포어로서, 일종의 락(lock) 메커니즘이며, 상호 배제(Mutex)와 유사한 개념입니다. 0은 잠김 상태를, 1은 해제된 상태를 나타냅니다.
- 계수 세마포어: 이는 동시에 여러 개의 공유 자원을 제어할 수 있습니다. 예를 들어, 세마포어가 3이라면, 동시에 최대 3개의 스레드나 프로세스가 공유 자원에 접근할 수 있습니다.
Semaphore 관련 함수
Semaphore 생성 함수
#include <window.h>
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount,
LONG lMaximumCount,
LPCTSTR lpName
);
Semaphore 반환 함수
#include <windows.h>
BOOL ReleaseSemaphore(
HANDLE hSemaphore,
LONG lReleaseCount,
LPLONG lpPreviousCount
);
이외의 Semaphore 소유 호출 함수와 소멸함수는 WaitForSingleObject와 CloseHandle은 Mutex와 동일하다.
세마포어 자세한 내용
https://namu.wiki/w/%EC%84%B8%EB%A7%88%ED%8F%AC%EC%96%B4
코드 예제 Git
https://github.com/latin9/Mutex
https://github.com/latin9/Semaphore
'TCP_IP 소켓 프로그래밍' 카테고리의 다른 글
TCP채팅서버 만들기 c++ 02 (0) | 2023.07.06 |
---|---|
TCP채팅서버 만들기 c++ 01 (0) | 2023.07.05 |
UDP 기반 서버/클라이언트 (0) | 2023.06.16 |
TCP 기반 서버 / 클라이언트에 대한 이해2 (에코 서버, TCP 내부 구조) (0) | 2023.06.14 |
TCP 기반 서버 / 클라이언트에 대한 이해1 (0) | 2023.06.13 |
댓글