Computer Science 기본 지식/운영체제 27

정적 라이브러리, 동적 라이브러리

라이브러리 관련 지식 정리. Library 라이브러리란 사용하고자하는 함수를 미리 컴파일하여 목적 코드로 만든 이후 목적 코드를 모아 만든 .lib을 링크하여 사용하는 것을 라이브러리라고 한다. 정적 라이브러리 Static Library (.lib 혹은 .a) 정적 라이브러리를 사용하여 자신의 프로젝트 코드를 컴파일 할 때 컴파일러는 사용자 함수에서 라이브러리 함수를 호출하는 경우 해당 함수의 목적 코드를 크게 두 가지 형태로 실행 파일에 담는다. 1. 사용자 함수를 목적 코드로 만드는 과정에서 라이브러리 함수 내용도 같이 담을 수 있다. (주로 인라인이 가능한 함수들) 2. 라이브러리 함수나 프로시저의 내용이 클 경우 등 해당 라이브러리 함수나 프로시저 실행 명령어(목적 코드)를 실행 파일에 포함시키되..

[C++ Thread] Lock Free Programming - (2) Lock Free Queue

LockFree 큐를 설계해본다. LockFree Queue LockFree Stack에 이어서 큐와 같은 경우 FIFO 특징이 있기 때문에 맨 앞을 가리키는 노드(Head)와 맨 뒤를 가리키는 노드(Tail)이 있어야한다. 큐의 설계 처음 큐에는 Head와 Tail이 일치하는 더미 노드가 하나 존재하며 데이터를 가지지 않는다. Push() : 현재 Tail의 노드(OldTail)에 데이터를 삽입하고 새로운 노드를 Tail로 만들어준다. 새로운 노드에 데이터를 할당하는 것이 아니다. Pop(): Head와 Tail이 일치하지 않다면, 큐는 적어도 하나의 데이터가 있는 것이다. 이 때 Head는 OldHead가 되고 OldHead의 다음 노드가 Head가 된다. Single Producer Single C..

[C++ Thread] Lock-Free Programming - (1) Lock Free ? / Lock Free Stack

Lock-Free 코드란? - Concurrency와 Scalibility를 가지는 동기화 방법 코드상 존재하는 블로킹/기다림을 제거하거나 줄이는 것 - 블록킹을 사용하면서 생기는 잠재적인 문제 경쟁 조건 (Race Condition): 잘못된 락의 사용 혹은 락의 부재 데드락 (DeadLock) : 락이 다른 스레드에 의해 잠긴 상태에서 영원히 해제가 안되는 상태 Simplicity vs Scalabilty : 락을 이용한 프로그램은 단순하다. 하지만 락에 의해 발생하는 병목 현상으로 사용자의 증가로 인한 성능 이슈가 발생한다 (Low Scalability). 블로킹에 의해 발생하는 콘보이 효과 / 우선순위 뒤집힘(Priority Inversion) 등. Compare And Exchange (CAS)..

[C++ Thread] 동기화 방법에 따른 성능 비교

쓰레드 동기화 - 유저 모드 동기화 커널 모드로 전환하지 않고 동기화를 수행한다. 커널 모드보다 빠르지만 기능이 제한적이다. 크리티컬 섹션 Critical Section 스핀락 인터락 함수 기반 Interlocked Family of Function SRWLock Slim Reader/Writer Lock - 커널 모드 동기화 커널 모드로 전환하여 커널이 제공하는 동기화 방법을 사용한다. 느리지만 더 다양한 기능을 사용할 수 있다. 뮤텍스 Mutex 세마포어 Semphore 이름있는 뮤텍스 Named Mutex 이벤트 Event CriticalSection 뮤텍스처럼 락을 걸고 임계 영역을 진입하며 공유 자원을 사용한 이후 다시 반납한다. 생성과 소멸에 관한 함수 // 생성 void InitializeC..

[Windows] 완료 루틴 (Completion Routine)과 APC (Asynchronous Procedure Call)

앞 포스트에서 비동기 중첩 I/O 작업이 완료가 되면 등록한 Overlapped 구조체의 이벤트 핸들이 Signaled 상태가 되고 그 결과를 GetOverlappedResult를 통해 확인할 수 있었다. 완료 루틴이란 이벤트 핸들을 따로 생성할 필요없이 I/O 작업이 완료되면 자동으로 실행되는 루틴을 가리킨다. 이는 Overlapped 구조체를 등록하는 과정과 마찬가지로 비동기 입출력을 실행하는 함수에 등록하여 사용한다. ex) WriteFileEx BOOL WriteFileEx( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCom..

[Windows] Overlapped I/O

비동기 I/O를 위한 Windows에서 제공하는 API를 정리한다. ※ 동기 I/O와 비동기 I/O 프로그램에서 수반되는 입출력을 현재 실행중인 프로세스나 스레드에서 어떻게 처리할 것 인지에 대한 방법이다. 여러 작업을 동시에 처리하여 다중 CPU를 사용하는 컴퓨터에서 CPU의 이용률을 최대화하는 것이 유리하다. 만약 프로그램의 주 쓰레드에서 I/O 입출력 동작을 필요로 하는 상황에서 입출력이 끝날때까지 블로킹 상태로 놓인다면 입출력이 완료되는 시점에서 다음 실행이 진행되기 때문에 동기적 (Synchronous) I/O를 수행하는 것이다. 하지만 이는, I/O 작업동안 주 쓰레드는 아무것도 하지 않기 때문에 CPU를 최대한으로 이용한다고 볼 수 없다. 반면에 비동기적 I/O는 입출력 동작을 요청하기만 하..

[운영체제] OS관련 용어

기본적인 OS관련 용어를 정리한다. RTOS vs OS RealTime OS는 일반 OS보다 반응 속도가 빠른 운영체제를 지칭한다. 주로 반응 속도가 중요한 시스템에서 사용되며 범용적인 역할을 하는 OS보다 할 수 있는 일이 제한적이다. 반응 시간에 데드 라인이 있을 정도로 제약이 있는 경우 Hard RTOS라고 하며 자동차의 ABS, 에어백 동작과 같은 안전 시스템이나 반응 시간이 중요한 첨단 무기 체계의 시스템을 예로 들 수 있다. 그밖에 일반적인 RTOS를 Soft RTOS라고 한다. 선점형 OS vs 비선점형 OS 선점형 OS: 프로세스마다 우선순위를 부여하고 현재 실행중인 프로세스보다 우선순위가 높은 프로세스가 생성되었다면 그 프로세스를 먼저 실행시키도록 한다. 사용자의 입력에 반응을 하는 프로..

[C++ Thread] Windows API에서 쓰레드 생성

Windows에서 사용할 수 있는 쓰레드를 알아본다. 1. CreateThread CreateThread를 이용하여 쓰레드를 생성할 수 있다. HANDLE WINAPI CreateThread( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ __drv_aliasesMem LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD lpThreadId ); lpThreadAttributes : 보안 속성을 결정한다. dwStackSize : 쓰레드 생성시 할당되는 스택 ..

[C++ Thread] 스핀 락 Spin Lock

다음 글을 참고하였습니다. www.codeproject.com/Articles/184046/Spin-Lock-in-C mutex나 critical section과 같은 원시 동기화 객체를 쓰는 경우, 다음의 일련의 사건들이 두 스레드 사이에서 일어난다. 1) Thead 1이 락 L을 획득하고 실행한다. 2) Thread 2가 락 L을 획득하려 하지만, 이미 소유자가 있기 때문에 차단당하고 문맥 교환을 일으킨다. 3) Thread 1이 락 L을 반납한다. 이 행동은 커널 모드에서 스레드 2에게 알림(Signal)을 주게 된다. 4) Thread 2가 깨어나고 락 L을 획득하고 문맥 교환을 일으킨다. 원시 동기화 객체를 사용하는 경우 최소 두 번의 문맥 교환이 포함된다. 스핀 락을 사용할 경우 이러한 값비싼..

[C++ Thread] 쓰레드 풀 Thread Pool

다음을 참고하여 작성하였습니다. 모두의 코드, 쓰레드 풀: modoocode.com/285 쓰레드 풀이란 특정 함수를 실행하는 워커(Worker) 쓰레드를 관리하는 객체이다. 다음과 같은 역할을 수행한다. - 요청받은 작업을 작업 큐에 삽입한다. - 대기 중인 워커 쓰레드 중 하나를 wakeup하여 작업을 큐에서 꺼내고 실행한다. - 다수의 쓰레드에서 접근하는 작업 큐는 뮤텍스로 보호한다. 쓰레드 풀 생성 워커 쓰레드를 생성하는 것으로 시작한다. ThreadPool::ThreadPool(size_t num_threads) : num_threads(num_threads), stop_all(false) { worker_threads.reserve(num_threads); for (size_t i = 0; i..