728x90

1. ๊ฒฝ์Ÿ์กฐ๊ฑด์ด๋ž€?

๋‘ ๊ฐœ ์ด์ƒ์˜ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๊ณต์œ  ์ž์›(์˜ˆ: ๋ณ€์ˆ˜, ๋ฆฌ์ŠคํŠธ ๋“ฑ)์— ๋™์‹œ์— ์ ‘๊ทผํ•˜๋ ค ํ•  ๋•Œ, ์‹คํ–‰ ์ˆœ์„œ์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š” ๋ฌธ์ œ

์˜ˆ์‹œ

int counter = 0;

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

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

t1.Start();
t2.Start();


๊ธฐ๋Œ€๊ฐ’์€ 2000์ด์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” 1500 ~ 2000 ์‚ฌ์ด์˜ ๊ฐ’์ด ๋‚˜์˜ฌ ์ˆ˜๋„ ์žˆ์Œ
์›์ž์ (atomic) ์—ฐ์‚ฐ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ

์›์ž์ (atomic) ์—ฐ์‚ฐ์ด๋ž€?

ํ•˜๋‚˜์˜ ์—ฐ์‚ฐ์ด โ€œ๋” ์ด์ƒ ์ชผ๊ฐค ์ˆ˜ ์—†๋Š” ๋‹จ์œ„โ€๋กœ ์ˆ˜ํ–‰๋˜๋Š” ๊ฒƒ
- ์‹คํ–‰ ์ค‘ ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋ผ์–ด๋“ค ์ˆ˜ ์—†๊ณ ,
- ๋ฐ˜๋“œ์‹œ ์ „๋ถ€ ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜, ์ „๋ถ€ ์‹คํŒจํ•จ. ์ค‘๊ฐ„ ์ƒํƒœ๊ฐ€ ์—†์Œ
์ฆ‰, โ€œํ•œ ๋ฒˆ์— ๋”ฑ ์ฒ˜๋ฆฌ๋œ๋‹คโ€ ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋จ

์™œ counter++๋Š” ์›์ž์ ์ด์ง€ ์•Š์€๊ฐ€?

counter++๋Š” 3๋‹จ๊ณ„๋กœ ๋‚˜๋‰˜๋Š” ์—ฐ์‚ฐ์ž„
1. counter ๊ฐ’์„ ์ฝ์Œ (read)
2. ๊ฐ’์— 1์„ ๋”ํ•จ (add)
3. ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ์ €์žฅํ•จ (write)
-> ์ด ์ค‘๊ฐ„์— ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๊ฐ€ counter ๊ฐ’์„ ๋ฐ”๊ฟ”๋ฒ„๋ฆด ์ˆ˜ ์žˆ์Œ
-> ๊ทธ๋ž˜์„œ ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„  ์˜๋„ํ•œ ๊ฐ’์ด ๋‚˜์˜ค์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ

2. ํฌ๋ฆฌํ‹ฐ์ปฌ ์„น์…˜(Critical Section)

์ •์˜
๊ฒฝ์Ÿ ์กฐ๊ฑด์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ ๋ธ”๋Ÿญ
-> ๋ฐ˜๋“œ์‹œ ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ ์‹คํ–‰ํ•ด์•ผ ์•ˆ์ „ํ•จ

3. ๋™๊ธฐํ™” ๊ธฐ๋ฒ•๋“ค

3-1. Mutex (Mutual Exclusion)

- ํ”„๋กœ์„ธ์Šค ๊ฐ„ ๋˜๋Š” ์“ฐ๋ ˆ๋“œ ๊ฐ„ ๋ฝ์„ ๊ฑธ๊ธฐ ์œ„ํ•œ ๋ฐฉ์‹
- ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ ๋ฎคํ…์Šค๋ฅผ ์†Œ์œ  ๊ฐ€๋Šฅ

3-2. Monitor / lock (C#์—์„œ ๊ฐ€์žฅ ํ”ํ•จ)

- ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” Monitor.Enter/Exit ๊ธฐ๋ฐ˜
- lock์€ ์“ฐ๊ธฐ ํŽธํ•˜๊ณ  ์Šค์ฝ”ํ”„ ๊ธฐ๋ฐ˜ ํ•ด์ œ๊ฐ€ ๋ณด์žฅ๋ผ์„œ ์•ˆ์ „ํ•จ

class Counter
{
    private int _count = 0;
    private readonly object _lock = new object();

    public void Increment()
    {
        lock (_lock)
        {
            _count++;
        }
    }

    public int GetValue()
    {
        lock (_lock)
        {
            return _count;
        }
    }
}


3-3. Semaphore

- ๋ฎคํ…์Šค๋Š” ํ•œ ๋ฒˆ์— 1๊ฐœ ์“ฐ๋ ˆ๋“œ๋งŒ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ์ง€๋งŒ,
- ์„ธ๋งˆํฌ์–ด๋Š” ๋™์‹œ ํ—ˆ์šฉ ์ˆ˜ ์ œํ•œ์ด ์žˆ์Œ (์˜ˆ: ๋™์‹œ์— 3๊ฐœ๊นŒ์ง€ ์ง„์ž… ํ—ˆ์šฉ)

3-4. SpinLock

- Lock์„ ๊ฑธ ๋•Œ, ์Šค๋ ˆ๋“œ๊ฐ€ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ ๋ฉˆ์ถ”๋Š” ๋Œ€์‹  ๊ณ„์† ๋ฃจํ”„๋ฅผ ๋Œ๋ฉด์„œ ํ™•์ธํ•˜๋Š” ๋ฐฉ์‹
- CPU ๋‚ญ๋น„๊ฐ€ ์žˆ์ง€๋งŒ, ์งง์€ ๋ฝ ๊ตฌ๊ฐ„์—์„œ ๋น ๋ฅธ ๋ฐ˜์‘์„ฑ์ด ์žˆ์Œ

4. ๋ฐ๋“œ๋ฝ(Deadlock)์ด๋ž€?

๋‘ ๊ฐœ ์ด์ƒ์˜ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์„œ๋กœ ์ƒ๋Œ€๋ฐฉ์˜ ๋ฝ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒํƒœ์—์„œ ๋น ์ ธ๋‚˜์˜ค์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ

์˜ˆ์‹œ
- Thread A๊ฐ€ Lock1์„ ์žก๊ณ  Lock2๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ ,
- Thread B๊ฐ€ Lock2๋ฅผ ์žก๊ณ  Lock1์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒฝ์šฐ -> ๋‘˜ ๋‹ค ๋ฉˆ์ถค

์˜ˆ๋ฐฉ ๋ฐฉ๋ฒ•:
- ํ•ญ์ƒ ๋ฝ์„ ๊ณ ์ •๋œ ์ˆœ์„œ๋กœ ํš๋“
- ํƒ€์ž„์•„์›ƒ ์„ค์ •์œผ๋กœ ํƒˆ์ถœ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค๊ณ„

5. Unity์—์„œ๋Š”?

Unity๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ ์ค‘์‹ฌ ๊ตฌ์กฐ์ด์ง€๋งŒ,
- Job System + Burst๋ฅผ ์“ฐ๊ฑฐ๋‚˜
- Task, ThreadPool, BackgroundWorker ๋“ฑ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๊ฒฝ์Ÿ ์กฐ๊ฑด ์ฃผ์˜ ํ•„์š”
Unity์˜ NativeArray๋Š” ์Šค๋ ˆ๋“œ ์•ˆ์ •ํ•˜์ง€ ์•Š์Œ -> NativeQueue ๊ฐ™์€ ๊ตฌ์กธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ Job System ๋‚ด์—์„œ๋งŒ ์ ‘๊ทผํ•ด์•ผ ํ•จ


๋ฐ˜์‘ํ˜•

+ Recent posts