Race condition (경쟁 조건) 관련 글

예전에 스레드를 공부하다가 Lockfree라는 것을 알게 되었었고 일단 뭐든 만들어보자는 마인드로 MPMC부터 무턱대고 만들었었는데, 지금 와서 생각해 보니 남는 것도 없고 너무 얄팍하게 안 것 같아서 차근차근 개념을 이해하기 위해 작성한 글입니다.. 😎 🔎 Race condition “경쟁은 왜 발생하는 것일까?” “경쟁 상태에 데이터를 읽고 쓰면 무슨 일이 벌어질까?“에 대한 명확한 이해가 먼저 필요했습니다. 상황별로 살펴보도록 하겠습니다. Case 1: Read - Read 어떤 한 데이터를 2개 또는 그 이상 되는 스레드가 모두 읽기만 한다면 아무 일도 일어나지 않습니다....

2026년 10월 06일 · 2 min · 255 words · JongBin

SPSC Queue 만들기

💡 SPSC란? Single-Producer / Single-Consumer 의 약자로 생산자와 소비자가 1:1인 관계를 뜻합니다. 리눅스에서 소켓을 다루다가 스레드간 데이터 전달이 필요해서 알아보니 SPSC Queue가 있다는것을 알게 되었습니다. 제 경우는 클라이언트의 연결을 담당하는는스레드에서 데이터 수신을 담당하는 스레드로 소켓(fd)을 전달해야 했는데 공용 컨테이너와 뮤텍스를 사용하면 스레드가 늘어나면 늘어날수록 오버헤드가 늘 것 같았습니다. 그래서 연결을 담당하는 스레드와 데이터를 수신하는 스레드의 생산-소비가 1:1인 관계에서 뮤텍스 없이 Lock-free 하게 구현해 보려고 합니다. 👍 🚀 구현 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 // spsc_queue....

2026년 10월 05일 · 4 min · 665 words · JongBin

Windows IOCP 이용해서 서버 만들기 - 1

예전에 소켓을 만들 때 비동기 처리(?)를 select() 함수를 이용해서 처리했었는데, 이 함수를 사용한 서버는 많은 동시 접속자 및 고성능에는 적합하지 않다고 해서 다른 방법을 찾아보기로 했습니다. Blocking 이 있으면 모두 동기식입니다. 왜 적합하지 않을까❓ FD_SET 비효율적인 사용 select() 호출 때마다 파일 디스크립터 배열을 다시 세팅해서 전달 polling 방식 select() 함수 내부에서는 파일 디스크립터를 순회하며 감지함 접속한 클라이언트가 많아질수록 성능이 떨어짐 파일 디스크립터 최대 개수 허용하는 최대 개수가 1024개 따라서 고성능 서버에서는 사용되지 않는다....

2025년 10월 25일 · 4 min · 816 words · JongBin

C++ Lock-free 메모리풀 구현

이전 글에서는 메모리풀의 개념과 싱글 스레드에서 사용할 메모리풀을 구현해 보았습니다. 이번 글은 thread-safe 한 메모리풀을 구현해 볼겁니다! 😄 ✅ mutex 와 lock-free 로 만들 수 있는데 이번 글은 lock-free 를 이용해서 만들겠습니다. 🚀 Lock-free 메모리풀 ✨ 공유 자원 _header 및 CAS 문제 해결을 위해 Tag 추가 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 #ifndef __LF_MEMORY_POOL_H__ #define __LF_MEMORY_POOL_H__ #include<algorithm> #include<cstring> #include<atomic> template<typename T, size_t capacity = 1024> class LFMemoryPool { struct LinkedList { LinkedList *next; }; using TaggedLinkedList = std::pair<LinkedList *, uint64_t>; static constexpr size_t alignment = std::max(alignof(T), alignof(LinkedList)); static constexpr size_t blockSize = std::max(sizeof(T), sizeof(LinkedList)); public: LFMemoryPool() : _chunk{0,} , _header({nullptr, 0}) { TaggedLinkedList header = _header....

2025년 10월 20일 · 2 min · 382 words · JongBin

C++ 메모리풀 개념 및 구현

프로그램이 런타임 중에 동적으로 메모리를 할당하려면 new/delete 키워드를 사용하여 운영체제한테 메모리를 요구합니다. 이 때 시스템 콜을 시작으로(커널 모드 진입) 전역 힙에서 요청한 크기의 블록을 찾고 Free list 를 관리하며 필요한 경우 메모리 페이지 테이블 업데이트 등의 작업을 수행하고 여러 스레드가 동시에 힙에 접근하는 것을 막기 위해 동기화 작업도 진행됩니다. 현대의 응용 프로그래밍은 이런 내부적인 상황까지 고려하여 설계하지 않겠지만, 최적화 관점에서 볼 때 동적으로 생성하는 것(메모리, 스레드 등등)을 최소화하면 좋다는 것입니다! 😄...

2025년 10월 19일 · 3 min · 529 words · JongBin