สัปดาห์ที่ 10 Concurrent Programming

จุดประสงค์การเรียนรู้

  1. อธิบายความแตกต่างระหว่าง Process และ Thread ได้
  2. ใช้แนวคิด Synchronization, Mutex และ Semaphore ได้
  3. วิเคราะห์สาเหตุของ Deadlock และแนวทางป้องกันได้

เนื้อหา

Process และ Thread

Process คือโปรแกรมที่กำลังทำงานพร้อมทรัพยากรของตนเอง ส่วน Thread คือหน่วยทำงานย่อยภายใน Process การใช้ Thread ช่วยให้โปรแกรมทำงานหลายงานพร้อมกันได้

Synchronization

เมื่อหลาย Thread ใช้ข้อมูลร่วมกันต้องมี Synchronization เพื่อป้องกัน Race Condition เครื่องมือที่ใช้บ่อยคือ Mutex และ Semaphore

Deadlock

Deadlock เกิดเมื่อหลาย Thread รอทรัพยากรของกันและกันจนไม่มีใครทำงานต่อได้ การออกแบบลำดับการล็อกและการกำหนด timeout ช่วยลดความเสี่ยงได้

Workshop

สร้างโปรแกรมหลาย Thread ที่ใช้ข้อมูลร่วมกัน ทดลองปัญหา Race Condition แล้วแก้ด้วย Mutex หรือ Semaphore

รายละเอียดการเรียนรู้

ผู้เรียนเริ่มจากการจำลองงานที่ทำพร้อมกัน เช่น การนับจำนวน การดาวน์โหลดข้อมูล หรือการประมวลผลหลายรายการ แล้วสังเกตว่าผลลัพธ์อาจผิดเมื่อหลาย Thread เขียนข้อมูลร่วมกันโดยไม่ควบคุม

การแก้ปัญหาไม่ได้หมายถึงการล็อกทุกอย่าง เพราะจะทำให้โปรแกรมช้า ผู้เรียนต้องระบุ critical section ให้ชัดเจนและล็อกเฉพาะช่วงที่จำเป็น พร้อมหลีกเลี่ยงการล็อกหลายทรัพยากรในลำดับที่ไม่แน่นอน

แนวปฏิบัติ

  1. ลดการแชร์ข้อมูลระหว่าง Thread
  2. ระบุ critical section ก่อนใช้ lock
  3. ใช้ lock ในช่วงสั้นที่สุด
  4. กำหนดลำดับการล็อกทรัพยากรให้คงที่

แบบฝึกหัด

สร้างโปรแกรมนับค่าหรือประมวลผลรายการด้วยหลาย Thread เปรียบเทียบผลลัพธ์ก่อนและหลังใช้ Synchronization

รูปแบบการนำเสนอเพิ่มเติมตามแม่แบบ

Concurrent Programming คือการออกแบบโปรแกรมให้ทำงานหลายงานในช่วงเวลาเดียวกัน ความท้าทายสำคัญคือการจัดการข้อมูลที่หลาย thread ใช้ร่วมกัน

%%{init: {'theme': 'base', 'themeVariables': {'background': '#282828','primaryColor': '#3c3836','primaryTextColor': '#fbf1c7','primaryBorderColor': '#fabd2f','lineColor': '#d3869b','secondaryColor': '#504945','tertiaryColor': '#665c54'}}}%%
flowchart TD
  A[Shared Data
ข้อมูลร่วม] --> B[Thread 1
เธรด 1] A --> C[Thread 2
เธรด 2] B --> D[Race Condition
แย่งแก้ข้อมูล] C --> D D --> E[Mutex/Semaphore
ควบคุมการเข้าถึง]

สมการ Speedup เบื้องต้น

S=T1Tp

ตัวอย่างโค้ดทดลอง

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;

int counter = 0;
mutex mtx;

void addOne() {
    lock_guard<mutex> lock(mtx); // ป้องกัน race condition
    counter++;
}

int main() {
    thread t1(addOne);
    thread t2(addOne);
    t1.join();
    t2.join();
    cout << counter << endl; // expected: 2
    return 0;
}
ปัญหา สาเหตุ วิธีป้องกัน
Race Condition thread แก้ข้อมูลพร้อมกัน mutex
Deadlock รอ lock กันเอง กำหนดลำดับ lock
Starvation บาง thread ไม่ได้ทำงาน ออกแบบ scheduling ให้เหมาะ

กลับรายวิชา