[OS] 멀티슀레드에서 겜쟁 상태 핎결: 상혞 배제 (뮀텍슀와 섞마포얎)

2025. 6. 2. 01:34·⚙ CS & Ʞ타 개발 자료
📌 였늘 죌제읞 겜쟁 상태와 상혞 배제는 멀티슀레드 왞에도 멀티프로섞슀에서도 발생할 수 있는 묞제읎지만
제가 멀티슀레드에 대핮 배우며 정늬한 낎용윌로, 멀티슀레드에 대핎서만 쀑점적윌로 얞꞉했습니닀.
착였가 없윌시Ꞟ!

✅ 멀티슀레드란?

읎전 Ꞁ에서 슀레드의 개념을 삎펎뎀습니닀.

 

⚙ 프로섞슀 / 슀레드 개념 정늬

📌 요앜프로귞랚: 얎느 작업을 하Ʞ 위핎 싀행될 수 있는 파음프로섞슀: 메몚늬에 올띌가고, 욎영첎제로부터 CPU륌 할당받아 싀행 쀑읞 프로귞랚슀레드: 프로섞슀 낎에서 독늜적윌로 싀행되는

syleeblog.tistory.com

 

멀티슀레드란 하나의 프로섞슀 안에 여러 개의 슀레드가 있는 상태륌 말합니닀.

슉, 하나의 프로섞슀 안에서 두 가지 읎상의 작업을 할 수 있습니닀.

 

 

크롬에서 여러 찜을 띄워 각자 작업할 수 있듯읎

멀티슀레드 환겜에서는 여러 작업을 동시에, 독늜적윌로 수행할 수 있닀는 장점읎 있습니닀.

예륌 듀얎, 칎칎였톡에서 파음을 전송하는 데 몇 쎈가 걞늬Ʞ도 하지만, ê·ž 시간 동안 사용자는 전송읎 끝나Ʞ륌 Ʞ닀늬는 게 아니띌 새로욎 톡을 볎낎는 등의 닀륞 행동을 자유롭게 할 수 있습니닀.

 

또한 서로 별개의 메몚늬 공간을 가지는 프로섞슀와 달늬

슀레드끌늬는 프로섞슀 낮 메몚늬륌 음부 공유하Ʞ 때묞에 멀티 프로섞슀에 비핎 자원곌 공간읎 절앜되는 횚곌가 있습니닀.

 

귞러나 동시에 접귌하고 싀행되는 흐늄읎 많닀는 것은 공유 자원을 둘러싌 묞제의 가능성도 컀진닀는 뜻읎Ʞ도 합니닀.

ê·ž 대표적읞 묞제로 교착 상태(Deadlock), êž°ì•„ 상태(Starvation), 겜쟁 상태(Race Condition) 등읎 있는데

읎 Ꞁ에서는 겜쟁 상태(Race Condition)에 대핮 자섞히 닀뀄볎겠습니닀.

 


🚀 겜쟁 상태 (Race Condition)

겜쟁 상태란 둘 읎상의 슀레드가 공유된 자원에 대핮 동시에 접귌하멎서 싀행 순서에 따띌 결곌가 달띌지는 묞제륌 말합니닀.

 

예륌 듀얎 볌까요?

public class Counter {
    private int count = 0;

    public void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

 

위의 increment() 메서드는 닚순히 count륌 1 슝가시킀는 윔드입니닀.

여러 슀레드가 동시에 읎 메서드륌 혞출하멎 얎떻게 될까요?

 

Thread t1 = new Thread(() -> {
    for (int i = 0; i < 1000; i++) {
        counter.increment();
    }
});

Thread t2 = new Thread(() -> {
    for (int i = 0; i < 1000; i++) {
        counter.increment();
    }
});

 

두 개의 슀레드에서 각각 1000번씩 슝가시쌰는데

결곌가 2000볎닀 작을 수 있습니닀.

 

묞제는 count++읎란 동작읎 사싀 섞 개의 동작윌로 나뉘Ʞ 때묞입니닀.

  1. count 값을 읜는닀
  2. 1을 더한닀
  3. 결곌륌 닀시 count에 저장한닀

읎 섞 동작 쀑간에 닀륞 슀레드가 끌얎듀멎, count 값은 엉뚱하게 슝가하거나 걎너뛰게 됩니닀.

 

예륌 듀얎, 두 슀레드가 아래와 같은 순서로 싀행된닀고 핎뎅시닀.

- 슀레드 A: count 값을 읜음 → (count == 0)
- 슀레드 B: count 값을 읜음 → (count == 0)
- 슀레드 A: 1을 더핮 1 저장
- 슀레드 B: 1을 더핮 1 저장

 

결곌적윌로 두 번 슝가했지만 싀제 값은 1입니닀.

 

읎 묞제륌 핎결하렀멎, 공유 자원에 대핮 슀레드듀읎 순서대로 접귌하도록 "동Ʞ화" 작업읎 필요합니닀.


🧪 핎결 전략

겜쟁 상태륌 핎결하Ʞ 위한 동Ʞ화 메컀니슘윌로 상혞배제에 대핮 알아볎겠습니닀.

💡 상혞배제(Mutual Exclusion)

음반적읞 프로섞슀 낮 윔드 구조입니닀.

윔드 쀑 공유 자원에 접귌하는 구역을 임계 구역(critical section)읎띌고 합니닀.

📌 임계 구역읎란? (critical section?)

둘 읎상의 프로섞슀에서 동시에 접귌핎서는 안 되는 공유 자원에 접귌하는 윔드 구역
(a piece of code that accesses a shared resources(data structure or device) that must not be concurrently accessed by more than one processes.)

 

여러 슀레드가 동시에 임계 구역에 진입한닀멎 겜쟁 상태가 발생하게 됩니닀.

귞래서 읎륌 방지하는 묞제륌 임계 구역 묞제(Critical Section Problem)읎띌고 부륎Ʞ도 합니닀.

 

읎륌 막Ʞ 위핎 슀레드가 임계 구역에 듀얎가Ʞ 전에

자신읎 임계 구역에서 작업하는 동안 닀륞 슀레드듀읎 진입하지 못하도록 lock을 섀정하고,

임계 구역에서의 작업읎 끝나멎 lock을 핎제하는 동작읎 필요합니닀.

 

슉, 읎믞 한 슀레드가 임계 구역에서 작업 쀑읎띌멎 닀륞 슀레드는 임계 구역에 진입하멎 안 됩니닀.

읎륌 상혞 배제(Mutual Exclusion)읎띌고 합니닀.

 

닀음은 멀티슀레드 환겜에서 상혞배제륌 구현하는 대표적읞 두 가지 동Ʞ화 메컀니슘

뮀텍슀와 섞마포얎에 대핮 삎펎뎅시닀.

✅ 뮀텍슀(Mutex)

"한 번에 하나만 듀얎올 수 있닀"

 

공유 자원에 대핮 한 번에 하나의 슀레드만 ì ‘ê·Œ 가능한 전략입니닀.

 

한 슀레드가 자원에 접귌하멎 풀멮 때까지 띜(lock)읎 걞늜니닀.

읎 띜을 풀 수 있는 걎 띜을 걎 핎당 슀레드 뿐입니닀.

읎 자원에 접귌하고자 하는 나뚞지 슀레드는 띜읎 풀멮 때까지 Ʞ닀늜니닀.

 

Java에서는 아래와 같읎 synchronized 킀워드륌 메서드에 붙여 increment() 메서드 싀행 전후로 띜을 걞 수 있습니닀.

public synchronized void increment() {
    count++;
}

 

synchronized 킀워드륌 읎용한 겜우 작업읎 끝난 슀레드가 띜을 반환할 때, 닀음윌로 띜을 획득할 슀레드가 ì–Žë–€ 슀레드음지에 대한 볎장읎 없Ʞ 때묞에

ì–Žë–€ 슀레드는 띜을 획득하지 못하고, 계속 접귌을 Ʞ닀늬는 êž°ì•„ 상태가 될 가능성읎 있습니닀.

(음반적윌로는 JVM읎 공정하게 띜을 분배하렀 합니닀.)

 

읎러한 묞제륌 핎결하Ʞ 위핎 명시적 띜을 사용하Ʞ도 합니닀. 대표적읞 예로 Java의 ReentrantLock읎 있습니닀. 

private final ReentrantLock lock = new ReentrantLock();

public void increment() {
    lock.lock();
    try {
        count++;
    } finally {
        lock.unlock();
    }
}

 

syncronized 킀워드와 명시적 띜 몚두 닀륞 슀레드에서 확읞할 수 있는 게 아니띌 하나의 슀레드 낎에서만 음얎나는 음입니닀.

따띌서 뮀텍슀에서는 띜을 획득한 슀레드만읎 띜을 핎제할 수 있습니닀.

읎처럌 뮀텍슀에서 띜은 소유권의 개념읎 있습니닀.

뮀텍슀의 목적은 한 슀레드가 ì–Žë–€ 공유 자원에 대핮 독점적윌로 작업을 끝마칠 때까지 볎혞하는 것읎Ʞ 때묞입니닀.

 

🔑 뮀텍슀에서 핵심은 한 번에 하나의 슀레드만 ì ‘ê·Œ 가능하도록 볎장한닀는 점입니닀.

 

✅ ì„žë§ˆí¬ì–Ž(Semaphore)

섞마포얎 역시 공유자원에 여러 슀레드가 접귌되는 것을 막는 방법읎지만

뮀텍슀와 닀륎게 반드시 한 번에 하나의 슀레드만 접귌할 수 있는 것은 아닙니닀.

섞마포얎에서는 동시에 정핎진 개수만큌의 슀레드가 공유 자원에 접귌할 수 있습니닀.

 

Semaphore띌는 정수형 칎욎터 변수(볎통 s로 표시)륌 읎용하여 동시에 공유 자원에 접귌할 수 있는 슀레드의 수륌 제한합니닀.

처음에 공유 자원에 접귌할 수 있는 동시 슀레드 수륌 N개로 정하멎, 최대 N개만 동시에 임계 구역에 진입할 수 있고,

귞볎닀 더 많은 슀레드가 접귌하렀고 하멎 뚌저 듀얎가 있던 슀레드가 나올 때까지 Ʞ닀렀알 합니닀.


"아니.. 동시에 하나의 슀레드만 임계 구역에 듀얎가알 한닀멎서요?! 섞마포얎가 상혞배제읞 ê±° 맞아요?"

 

겜쟁 상태륌 막Ʞ 위핎 한 시점에 였직 하나의 슀레드만 공유 자원에 접귌할 수 있도록 제한하는 것읎 상혞 배제입니닀.

상혞 배제륌 구현하는 도구로 였늘 삎펎볞 뮀텍슀와 섞마포얎 등읎 있는거죠.

만앜 섞마포얎에서 동시에 공유 자원에 접귌할 수 있는 슀레드의 개수륌 "1개"로 섀정한닀멎

뮀텍슀처럌 한 번에 하나의 슀레드만 듀얎가겠죠? 읎러한 섞마포얎륌 Binary Semaphore띌고 합니닀.

Binary Semaphore로 구현하멎 상혞 배제륌 구현할 수 있습니닀.

였늘 배욎 상혞 배제 왞에도 동Ʞ화 용도로 섞마포얎륌 사용하Ʞ도 합니닀.

 

읎 Semaphore에서는 P 연산곌 V 연산을 읎용핎 자원에 접귌합니닀.

P()는 임계 구역에 진입하고자 할 때 혞출하고, V()는 임계 구역에서 나올 때 혞출합니닀.

P(s) {

    while(S <= 0) {
    	do wait; // no operation
    }
    S--;
}

V(s) {
	S++;
}

 

📌 P 연산

공유 자원을 얻Ʞ 위핎 임계 구역에 듀얎가Ʞ 전 entry section(진입 구간)에서 P 연산을 합니닀.

읎때 섞마포얎 값을 점검하여 누군가 읎 자원을 사용하는지 알 수 있습니닀.

 

만앜 섞마포얎 s > 0 읎멎, 핎당 슀레드가 자원에 접귌할 수 있닀는 의믞입니닀.

s륌 1 감소시킀고 임계 구역에 진입합니닀.

 

반멎 s <= 0읎멎 닀륞 슀레드가 읎믞 임계 구역에서 작업 쀑읎띌는 의믞읎므로 s가 닀시 양수가 될 때까지 대Ʞ합니닀.

 

읎때 s는 묎엇을 의믞할까요? 바로 "현재 임계 구역에 진입 가능한 슀레드의 수"입니닀.

 

📌 V 연산

V연산은 점유하고 있던 공유 자원을 풀얎죌는 것입니닀.

임계 구역에서 벗얎나 exit section에 ì ‘ì–Žë“€ 때 V 연산을 수행합니닀.

 

슀레드가 공유 자원에 대한 작업을 끝낎멎 섞마포얎 s의 값읎 1 슝가합니닀.

읎때 대Ʞ하고 있던(sleep 상태읎던) 슀레드가 있었닀멎 잠에서 깚얎나 공유 자원에 접귌하게 됩니닀.

 

섞마포얎는 뮀텍슀와 달늬 띜에 대한 소유권 개념읎 없는 공유 자원 ì ‘ê·Œ 제얎 도구입니닀.

섞마포얎륌 사용하는 ì–Žë–€ 슀레드띌도 V 연산윌로 섞마포얎 값을 슝가시쌜 자원을 핎제할 수 있습니닀.

 

V ì—°ì‚°ì€ “공유 ìžì›ì˜ ì‚¬ìš©ìŽ ëë‚¬ìŒì„ ì•ŒëŠŽ ì±…임읎 ìžˆëŠ” ìŠ€ë ˆë“œ”가 í˜žì¶œí•©ë‹ˆë‹€.
읎 슀레드는 반드시 P 연산을 했던 같은 슀레드음 필요는 없습니닀. (묌론 같아도 됩니닀.)

 

예륌 듀얎 읎런 겜우가 있닀고 합시닀. (찞고로 읎 예시는 욎영첎제에서 많읎 예시로 드는 생산자 - 소비자 묞제륌 닚순화한 버전입니닀.)

  • 🧑‍🌟 생산자 Producer: 상품을 생산핎 마튞에 납품핚
  • 🧺 소비자 Consumer: 마튞에서 상품을 구입핚
  • 묞제: 소비자는 마튞에 상품읎 없윌멎 Ʞ닀렀알 핹
    • ➡ 생산자가 마튞에 납품했을 때 소비자에게 "읎제 사!"하고 신혞륌 쀘알 핹

읎때 섞마포얎는 현재 마튞에 상품 재고가 몇 개 있는지륌 나타낮는 숫자 칎욎터입니닀.

Semaphore items = new Semaphore(0);  // 현재 마튞에 상품읎 0개 있닀고 가정

Thread producer = new Thread(() -> {
    while (true) {
        produceItem();
        items.release();  // V 연산! 상품 하나 추가했얎!
    }
});

Thread consumer = new Thread(() -> {
    while (true) {
        items.acquire();  // P 연산! 재고가 없윌멎 Ʞ닀늌
        consumeItem();	// 상품 구입
    }
});

 

Producer는 V 연산만, Consumer는 P 연산만 합니닀.

읎로썚 생산자는 소비자에게 묌걎을 추가했닀고 알늬고, 소비자는 생산자에게 묌걎읎 필요하닀고 알늎 수 있죠.

 

섞마포얎는 "누가" 자원에 접귌했는지가 쀑요한 게 아니띌
"몇 개의 슀레드"가 자원에 접귌했는지가 쀑요하Ʞ 때묞에 누구나 띜을 핎제할 수 있습니닀.

 

 

정늬하자멎,

 

뮀텍슀에서는 하나의 자원에 동시에 하나의 슀레드만읎 접귌할 수 있었고, 띜을 섀정한 슀레드만 띜을 핎제할 수 있습니닀.

(동Ʞ화 대상읎 하나)

섞마포얎에서는 믞늬 지정한 최대 N개의 슀레드가 하나의 자원에 동시 접귌할 수 있습니닀. 누구나 띜을 핎제할 수 있습니닀.

(동Ʞ화 대상읎 하나 읎상)


💡 요앜

멀티슀레드 환겜에서는

여러 슀레드가 공유 자원에 동시에 접귌하멎서

데읎터 불음치나 예Ʞ치 않은 동작 묞제가 음얎날 수 있습니닀.

 

읎륌 ë°©ì§€í•˜ë €ë©Ž ë™ì‹œì— ì‹€í–‰ë˜ëŠ” ìŠ€ë ˆë“œ ê°„ ìžì› ì ‘귌을 ì¡°ìœší•Žì•Œ í•˜ë©°,
읎륌 위핎 뮀텍슀(Mutex), 섞마포얎(Semaphore)와 같은 동Ʞ화 도구륌 사용합니닀.

 

  • 🧵 멀티슀레드 환겜(Multi-Thread): 동시에 여러 작업읎 가능하지만, 공유 자원 충돌 위험읎 있음
  • ⚠ 겜쟁 상태(Race Condition): 여러 슀레드가 동시에 같은 자원에 접귌할 때 싀행 순서에 따띌 였류 발생
  • ✅ 상혞 배제(Mutual Exclusion): 읎믞 임계 구역(critical section)에서 작업 쀑읞 슀레드가 있닀멎, 닀륞 슀레드는 ì ‘ê·Œ 불가
  • 🔒 뮀텍슀 (Mutex): 한 번에 하나만 ì ‘ê·Œ 가능, 띜 소유자만 핎제 가능
  • 🟢 섞마포얎 (Semaphore): 동시에 여러 슀레드 ì ‘ê·Œ 가능, 소유자 ꎀ계 없읎 핎제 가능

 

찞고자료

  • 멀티 프로섞슀 vs 멀티 슀레드 비교 완전 쎝정늬
  • 슀레드(Thread), 멀티슀레드(Multi-Thread)!
  • 겜쟁 상태(Race Condition)
  • [Thread] 뮀텍슀, 섞마포얎, 몚니터의 슀레드 동Ʞ화와 구현 예제
  • ꎑ욎대학교 시슀템프로귞래밍 교곌목 강의자료
  • + 팀원 한상은 님의 Ꞁ
반응형

'⚙ CS & Ʞ타 개발 자료' 칎테고늬의 닀륞 Ꞁ

로컬 캐시 & 분산 캐시 읎핎하Ʞ  (1) 2025.06.12
캐시(Cache) 개념 쉜게 정늬하Ʞ  (1) 2025.06.03
⚙ 프로섞슀(Process) / 슀레드(Thread) 개념 정늬  (3) 2025.06.02
디버깅의 쀑요성  (0) 2025.05.14
[깃허람] Codecov 적용하여 PR에 테슀튞 컀버늬 뱃지 달Ʞ  (1) 2025.04.25
'⚙ CS & Ʞ타 개발 자료' 칎테고늬의 닀륞 Ꞁ
  • 로컬 캐시 & 분산 캐시 읎핎하Ʞ
  • 캐시(Cache) 개념 쉜게 정늬하Ʞ
  • ⚙ 프로섞슀(Process) / 슀레드(Thread) 개념 정늬
  • 디버깅의 쀑요성
소영 🍀
소영 🍀
Hello World ✹
  • 소영 🍀
    Soyoung's Dev Lab
    소영 🍀
  • 전첎
    였늘
    얎제
  • Ꞁ쓰Ʞ ꎀ늬
    • 분류 전첎볎Ʞ (47)
      • 📢 게시판 (0)
      • 📚 자료구조 & 알고늬슘 (1)
      • 🌿Spring (15)
      • ☕Java (8)
      • 📊 데읎터베읎슀 (3)
      • 📀 배포 (4)
        • Docker (4)
        • AWS (0)
      • ⚙ CS & Ʞ타 개발 자료 (14)
      • 🖥 프로젝튞 (0)
      • 👩‍💻 활동 & 후Ʞ (0)
      • 🍵 읎알Ʞ (2)
  • 랔로귞 메뉎

    • 태귞
  • 링크

    • github
    • velog
  • 공지사항

  • 읞Ʞ Ꞁ

  • 태귞

    GIT
    위큎늬 페읎퍌
    docker
    데읎터베읎슀
    배포
    알고늬슘
    객첎지향프로귞래밍
    서버
    Spring Security
    Java
    Spring
    윔드잇 슀프늰튞
    개발
    윔딩테슀튞
    자료구조
  • 최귌 댓Ꞁ

  • hELLO· Designed By정상우.v4.10.3
소영 🍀
[OS] 멀티슀레드에서 겜쟁 상태 핎결: 상혞 배제 (뮀텍슀와 섞마포얎)
상닚윌로

티슀토늬툎바