λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ–₯️/C#

[C#] μŠ€λ ˆλ“œ(Thread)

by HanaV 2023. 10. 11.
728x90
 
 

μŠ€λ ˆλ“œ(Thread)

 

λ©€ν‹° μŠ€λ ˆλ“œ

λ©€ν‹° μŠ€λ ˆλ”©μ€ 말 κ·ΈλŒ€λ‘œ ν•˜λ‚˜μ˜ ν”„λ‘œκ·Έλž¨μ—μ„œ μ—¬λŸ¬ 개의 μŠ€λ ˆλ“œλ₯Ό λ™μ‹œμ— μ‹€ν–‰ν•˜λŠ” 것을 μ˜λ―Έν•œλ‹€. 각 μŠ€λ ˆλ“œλŠ” λ…λ¦½μ μœΌλ‘œ μ‹€ν–‰λ˜λ©°, 병렬 μ²˜λ¦¬κ°€ κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— μ„±λŠ₯이 ν–₯상될 수 μžˆλ‹€. ν•˜μ§€λ§Œ λ„ˆλ¬΄ κ³Όν•œ λ©€ν‹° μŠ€λ ˆλ”©μ€ 였히렀 μ„±λŠ₯을 μ €ν•˜μ‹œν‚€κ³ , κ΅¬ν˜„μ΄ λ³΅μž‘ν•˜κΈ° λ•Œλ¬Έμ— μ μ ˆν•œ μƒν™©μ—μ„œ μ‚¬μš©ν•˜μ—¬μ•Ό ν•œλ‹€.

 

μŠ€λ ˆλ“œ μ‹œμž‘ν•˜λŠ” 법

1. Thread μΈμŠ€ν„΄μŠ€ 생성
2. Thread.Start()둜 μŠ€λ ˆλ“œ μ‹œμž‘
3. Thread.Join()으둜 μŠ€λ ˆλ“œ μ’…λ£Œ λŒ€κΈ°

// No Parameter
Thread thread = new Thread(Run);
thread.Start();
thread.Join();

// Parameter exist
Thread thread2 = new Thread(() => Run2(2, 3));
thread2.Start();
thread2.Join();

Thread.Start()λŠ” 말 κ·ΈλŒ€λ‘œ μŠ€λ ˆλ“œλ₯Ό μ‹œμž‘ν•œλ‹€λŠ” 것이기 λ•Œλ¬Έμ— 잘 이해가 λ˜μ§€λ§Œ, Tread.Join()은 μ΄ν•΄ν•˜κΈ° μ• λ§€ν•  μˆ˜λ„ μžˆλ‹€. thread.Join()은 threadκ°€ μ‹œμž‘λ˜κ³  μ’…λ£Œλ  λ•ŒκΉŒμ§€ μž‘μ—…μ„ λ©ˆμΆ”κ³  κΈ°λ‹€λ¦°λ‹€λŠ” λœ»μ΄λ‹€.

Join을 ν™œμš©ν•˜κΈ° μœ„ν•΄ λ¨Όμ € 두 λ©”μ„œλ“œλ₯Ό λ§Œλ“€μ—ˆλ‹€.
DoWork1은 5초λ₯Ό μ„Έκ³ , DoWork2λŠ” 2초λ₯Ό μ„Όλ‹€.

static void DoWork1()
{
    for (int i = 1; i <= 5; i++) {
        Thread.Sleep(1000);
        Console.WriteLine($"thread1: {i} sec");
    }
    Console.WriteLine("Work 1 completed.");
}

static void DoWork2()
{
    for (int i = 1; i <= 2; i++) {
        Thread.Sleep(1000);
        Console.WriteLine($"thread2: {i} sec");
    }
    Console.WriteLine("Work 2 completed.");
}

두 λ©”μ„œλ“œλ₯Ό μΈμŠ€ν„΄μŠ€λ‘œ κ°€μ§€λŠ” μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•΄μ„œ μ•„λž˜μ™€ 같은 μˆœμ„œλ‘œ μ‹€ν–‰μ‹œν‚€λ©΄,

Thread thread1 = new Thread(DoWork1);
Thread thread2 = new Thread(DoWork2);

thread1.Start();
thread2.Start();

thread1.Join();
thread2.Join();

Console.WriteLine("Both threads have completed their work.");
Console.WriteLine();

thread1이 μ’…λ£ŒλŒ€κΈ°λ˜κΈ° 전에 thread2도 start λ˜μ—ˆμœΌλ‹ˆ μ•„λž˜μ™€ 같은 κ²°κ³Όκ°€ λ‚˜μ˜¨λ‹€.

thread2: 1 sec
thread1: 1 sec
thread2: 2 sec
Work 2 completed.
thread1: 2 sec
thread1: 3 sec
thread1: 4 sec
thread1: 5 sec
Work 1 completed.
Both threads have completed their work.

λ§Œμ•½ μˆœμ„œλ₯Ό μ΄λ ‡κ²Œ λ°”κΏ”μ„œ thread2κ°€ μ‹œμž‘λ˜κΈ° 전에 thread1이 λ¨Όμ € μ’…λ£Œλ˜λ„λ‘ Join을 λ„£μœΌλ©΄ μ•„λž˜μ™€ 같이 κ²°κ³Όκ°€ 바뀐닀.

thread1.Start();
thread1.Join();

thread2.Start();
thread2.Join();
thread1: 1 sec
thread1: 2 sec
thread1: 3 sec
thread1: 4 sec
thread1: 5 sec
Work 1 completed.
thread2: 1 sec
thread2: 2 sec
Work 2 completed.
Both threads have completed their work.

 

μŠ€λ ˆλ“œ μ€‘μ§€μ‹œν‚€κΈ°

μŠ€λ ˆλ“œλ₯Ό μ·¨μ†Œμ‹œν‚€λŠ” Abort() λ©”μ„œλ“œλ„ μžˆμ§€λ§Œ, ꢌμž₯λ˜μ§€ μ•ŠλŠ”λ‹€. λ§Œμ•½ thread Start()κ°€ 계속 λ°˜λ³΅λ˜λŠ” 반볡문 μ•ˆμ— ν¬ν•¨λ˜μ–΄ μžˆλ‹€λ©΄, μŠ€λ ˆλ“œ μ’…λ£Œ ν”Œλž˜κ·Έ 등을 μ‚¬μš©ν•΄μ„œ μŠ€λ ˆλ“œλ₯Ό μˆ˜ν–‰ν•  것인지 μ•ˆν•  것인지λ₯Ό νŒλ‹¨ν•˜κ²Œ ν•˜κ±°λ‚˜, Interruptλ₯Ό μ‚¬μš©ν•΄μ„œ μ€‘μ§€μ‹œν‚€λŠ” 것이 μ’‹λ‹€.

Interrupted λ©”μ„œλ“œλ₯Ό μž‘λ™μ‹œν‚€λ©΄, ThreadInterruptedException이 λ°œμƒν•˜κ³ , 이 exception이 λ°œμƒν•˜λ©΄ ν˜„μž¬ μŠ€λ ˆλ“œλ₯Ό μ€‘λ‹¨μ‹œν‚¨λ‹€. 
μ•„λž˜μ™€ 같이 try catch둜 ThreadInterruptedException을 μž‘μ„ 수 μžˆλ‹€.

try {
    int count = 0;
    while (true) {
        Thread.Sleep(1000);
        count++;
        Console.WriteLine($"{count} sec");

        if (count == n) {
            Thread.CurrentThread.Interrupt();
        }
    }
}
catch (ThreadInterruptedException) {
    Console.WriteLine("Thread was interrupted.");
}

μœ„ ν•¨μˆ˜λ₯Ό DoWork(int n) λ©”μ„œλ“œλΌκ³  ν•˜κ³  μ‹€ν–‰μ‹œν‚€λ©΄

static void Main()
{
    Thread thread = new Thread(() => DoWork(5));
    Console.WriteLine($"Thread State: {thread.ThreadState}");

    thread.Start();
    Console.WriteLine($"Thread State: {thread.ThreadState}");

    thread.Join();
    Console.WriteLine($"Thread State: {thread.ThreadState}");
}
Thread State: Unstarted
Thread State: Running
Thread is starting.
1 sec
2 sec
3 sec
4 sec
5 sec
Thread was interrupted.
Thread State: Stopped

μ΄λ ‡κ²Œ μ‹€ν–‰λœλ‹€.

μŠ€λ ˆλ“œ μžμ›μ„ μ œλŒ€λ‘œ ν•΄μ œν•˜μ§€ μ•ŠμœΌλ©΄ λ©”λͺ¨λ¦¬μ™€ μžμ›μ΄ λˆ„μˆ˜λ˜κΈ° λ•Œλ¬Έμ— μ„±λŠ₯을 μ €ν•˜μ‹œν‚€κ²Œ λœλ‹€. Joinκ³Ό Interrupt, 그리고 ν•΄μ œν•˜κΈ° μœ„ν•œ flag λ“±μ˜ 방법을 μ‚¬μš©ν•΄μ„œ μŠ€λ ˆλ“œλ₯Ό μ œλ•Œ ν•΄μ œν•˜μ—¬μ•Ό ν•œλ‹€.

728x90

"); wcs_do();