Skip to content

Part 6: Concurrency Advanced

Concurrency là nghệ thuật làm nhiều việc cùng lúc — unlock sức mạnh của CPU đa nhân.

Tại sao Concurrency?

Trong thế giới hiện đại, mọi CPU đều có nhiều core. Một chương trình single-threaded chỉ sử dụng 1 core — lãng phí 75% sức mạnh trên CPU 4-core, 87.5% trên CPU 8-core!

┌─────────────────────────────────────────────────────────────────┐
│                    CPU UTILIZATION                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Single-threaded Program:                                       │
│  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐                           │
│  │ BUSY │ │ IDLE │ │ IDLE │ │ IDLE │  ← 75% wasted!            │
│  │ Core │ │ Core │ │ Core │ │ Core │                           │
│  └──────┘ └──────┘ └──────┘ └──────┘                           │
│                                                                 │
│  Multi-threaded Program:                                        │
│  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐                           │
│  │ BUSY │ │ BUSY │ │ BUSY │ │ BUSY │  ← 100% utilized!         │
│  │ Core │ │ Core │ │ Core │ │ Core │                           │
│  └──────┘ └──────┘ └──────┘ └──────┘                           │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Process vs Thread

🏭 Analogy: Nhà máy sản xuất

Hãy tưởng tượng một nhà máy sản xuất:

Khái niệmAnalogyMô tả
ProcessNhà máyMột chương trình đang chạy — có không gian riêng, tài nguyên riêng
ThreadCông nhânĐơn vị thực thi trong process — chia sẻ tài nguyên của nhà máy
MemoryKho hàngProcess có kho riêng, các thread chia sẻ chung

Memory Model

┌─────────────────────────────────────────────────────────────────┐
│                        PROCESS MEMORY                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │                    SHARED MEMORY                        │   │
│   │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐     │   │
│   │  │    Heap     │  │   Global    │  │    Code     │     │   │
│   │  │  (dynamic)  │  │  Variables  │  │  Segment    │     │   │
│   │  └─────────────┘  └─────────────┘  └─────────────┘     │   │
│   └─────────────────────────────────────────────────────────┘   │
│                              ▲                                   │
│         ┌────────────────────┼────────────────────┐              │
│         │                    │                    │              │
│   ┌─────┴─────┐        ┌─────┴─────┐        ┌─────┴─────┐       │
│   │  Thread 1 │        │  Thread 2 │        │  Thread 3 │       │
│   │  ┌─────┐  │        │  ┌─────┐  │        │  ┌─────┐  │       │
│   │  │Stack│  │        │  │Stack│  │        │  │Stack│  │       │
│   │  └─────┘  │        │  └─────┘  │        │  └─────┘  │       │
│   │  (riêng)  │        │  (riêng)  │        │  (riêng)  │       │
│   └───────────┘        └───────────┘        └───────────┘       │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

💡 KEY INSIGHT

  • Heap & Global: Tất cả threads chia sẻ → Có thể giao tiếp nhưng cũng có thể xung đột!
  • Stack: Mỗi thread có stack riêng → Biến local là an toàn.

Process vs Thread — So sánh chi tiết

Đặc điểmProcessThread
MemoryRiêng biệt hoàn toànChia sẻ heap, global
Tạo mớiChậm (~100ms)Nhanh (~1ms)
Context switchĐắt (flush cache)Rẻ hơn
CommunicationIPC (sockets, pipes)Shared memory
Crash impactChỉ process đóToàn bộ process chết
Use caseIsolation (Chrome tabs)Parallel tasks

C++ Concurrency History

┌─────────────────────────────────────────────────────────────────┐
│                 C++ CONCURRENCY EVOLUTION                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Pre-C++11:    Platform-specific (POSIX, Win32)                 │
│                pthread, CreateThread() — không portable          │
│                                                                 │
│  C++11:        std::thread, std::mutex, std::condition_variable │
│                → Portable concurrency!                          │
│                                                                 │
│  C++14:        std::shared_timed_mutex                          │
│                                                                 │
│  C++17:        std::scoped_lock, std::shared_mutex              │
│                Parallel STL algorithms                          │
│                                                                 │
│  C++20:        std::jthread (auto-join)                         │
│                std::latch, std::barrier, std::counting_semaphore│
│                Coroutines (co_await)                            │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

📌 PENALGO Focus

Chúng tôi tập trung vào C++11/17 vì đây là baseline phổ biến nhất trong industry. C++20 features sẽ được đề cập khi relevant.


Module Structure

📘 Part 1: Threads & Mutexes (Module này)

TopicDescription
std::threadTạo và quản lý threads
Race ConditionsDemo lỗi và hiểu nguyên nhân
Synchronizationmutex, lock_guard, unique_lock
DeadlocksDining Philosophers Problem

📙 Part 2: Advanced

TopicDescription
async & futureHigher-level abstractions
AtomicsLock-free programming basics
Condition VariablesProducer-Consumer pattern
Thread PoolReusing threads efficiently

Prerequisites

📋 YÊU CẦU


Các vấn đề của Concurrency

┌─────────────────────────────────────────────────────────────────┐
│                 CONCURRENCY CHALLENGES                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ⚠️ RACE CONDITIONS                                             │
│     Nhiều threads truy cập cùng data → kết quả không xác định   │
│                                                                 │
│  ☠️ DEADLOCKS                                                   │
│     Threads chờ lẫn nhau mãi mãi → program treo                 │
│                                                                 │
│  🐌 STARVATION                                                  │
│     Một thread không bao giờ được chạy                          │
│                                                                 │
│  🔄 LIVELOCK                                                    │
│     Threads liên tục thay đổi state nhưng không tiến triển      │
│                                                                 │
│  💥 DATA CORRUPTION                                             │
│     Dữ liệu bị hỏng do concurrent writes                        │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Learning Path

Part 1: Threads & Mutexes

  1. 🧵 std::thread — Bắt đầu tạo threads
  2. ⚠️ Race Conditions — Hiểu vấn đề
  3. 🔒 Synchronization — Giải pháp với mutex
  4. ☠️ Deadlocks — Tránh bẫy chết người

Part 2: Advanced 5. 🚀 async & future — Higher abstractions 6. ⚛️ Atomics — Lock-free basics 7. 🔔 Condition Variables — Producer-Consumer 8. 🏊 Thread Pool — Reusing threads


"The first rule of concurrency is: Don't use it. The second rule: If you must, don't share mutable state." — Unknown