산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C# 멀티스레딩 마스터하기: 성능과 효율성 향상

스레드(thread)는 프로그램의 실행 경로로 정의됩니다. 각 스레드는 고유한 제어 흐름을 정의합니다. 애플리케이션이 복잡하고 시간이 많이 걸리는 연산을 포함하는 경우, 각 스레드가 특정 작업을 수행하도록 서로 다른 실행 경로나 스레드를 설정하는 것이 종종 유용합니다.

스레드는 경량 프로세스(lightweight processes)입니다. 스레드 사용의 일반적인 예는 최신 운영체제에서 동시 프로그래밍을 구현하는 것입니다. 스레드 사용은 CPU 사이클 낭비를 줄이고 애플리케이션의 효율성을 높입니다.

지금까지 단일 스레드가 애플리케이션의 실행 인스턴스인 단일 프로세스로 실행되는 프로그램을 작성했습니다. 그러나 이 방식으로는 애플리케이션이 한 번에 한 가지 작업만 수행할 수 있습니다. 이를 여러 작업으로 나누어 동시에 실행하려면 더 작은 스레드로 분할할 수 있습니다.

스레드 수명 주기

스레드의 수명 주기는 System.Threading.Thread 클래스의 객체가 생성될 때 시작되고 스레드가 종료되거나 실행을 완료하면 끝납니다.

스레드 수명 주기의 다양한 상태는 다음과 같습니다.

메인 스레드

C#에서 System.Threading.Thread 클래스는 스레드 작업에 사용됩니다. 멀티스레드 애플리케이션에서 개별 스레드를 생성하고 접근할 수 있습니다. 프로세스에서 실행되는 첫 번째 스레드를 메인(main) 스레드라고 합니다.

C# 프로그램이 실행을 시작하면 메인 스레드가 자동으로 생성됩니다. Thread 클래스를 사용하여 생성된 스레드를 메인 스레드의 자식 스레드라고 합니다. Thread 클래스의 CurrentThread 속성을 사용하여 스레드에 접근할 수 있습니다.

다음 프로그램은 메인 스레드 실행을 보여줍니다.

Live Demo
using System;
using System.Threading;
namespace MultithreadingApplication {
    class MainThreadProgram {
        static void Main(string[] args) {
            Thread th = Thread.CurrentThread;
            th.Name = "MainThread";
            Console.WriteLine("This is {0}", th.Name);
            Console.ReadKey();
        }
    }
}

위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.

This is MainThread

Thread 클래스의 속성과 메서드

다음 표는 Thread 클래스의 가장 일반적으로 사용되는 속성들입니다.

번호속성 및 설명
1

CurrentContext

스레드가 실행 중인 현재 컨텍스트를 가져옵니다.

2

CurrentCulture

현재 스레드의 문화권(culture)을 가져오거나 설정합니다.

3

CurrentPrinciple

현재 스레드의 보안 주체(역할 기반 보안)를 가져오거나 설정합니다.

4

CurrentThread

현재 실행 중인 스레드를 가져옵니다.

5

CurrentUICulture

리소스 관리자가 런타임에 문화권별 리소스를 조회하는 데 사용하는 현재 문화권을 가져오거나 설정합니다.

6

ExecutionContext

현재 스레드의 다양한 컨텍스트 정보를 포함하는 ExecutionContext 객체를 가져옵니다.

7

IsAlive

현재 스레드의 실행 상태를 나타내는 값을 가져옵니다.

8

IsBackground

스레드가 백그라운드 스레드인지 여부를 나타내는 값을 가져오거나 설정합니다.

9

IsThreadPoolThread

스레드가 관리되는 스레드 풀에 속하는지 여부를 나타내는 값을 가져옵니다.

10

ManagedThreadId

현재 관리되는 스레드의 고유 식별자를 가져옵니다.

11

Name

스레드 이름을 가져오거나 설정합니다.

12

Priority

스레드의 예약 우선순위를 나타내는 값을 가져오거나 설정합니다.

13

ThreadState

현재 스레드의 상태를 포함하는 값을 가져옵니다.

다음 표는 Thread 클래스의 가장 일반적으로 사용되는 메서드들입니다.

번호메서드 및 설명
1

public void Abort()

호출된 스레드에서 ThreadAbortException을 발생시켜 스레드 종료 프로세스를 시작합니다. 이 메서드 호출은 보통 스레드를 종료시킵니다.

2

public static LocalDataStoreSlot AllocateDataSlot()

모든 스레드에 이름이 없는 데이터 슬롯을 할당합니다. 더 나은 성능을 위해 ThreadStaticAttribute로 표시된 필드를 사용하세요.

3

public static LocalDataStoreSlot AllocateNamedDataSlot(string name)

모든 스레드에 이름이 있는 데이터 슬롯을 할당합니다. 더 나은 성능을 위해 ThreadStaticAttribute로 표시된 필드를 사용하세요.

4

public static void BeginCriticalRegion()

스레드 중단이나 처리되지 않은 예외의 영향이 애플리케이션 도메인의 다른 작업을 위태롭게 할 수 있는 코드 영역에 진입하려 함을 호스트에 알립니다.

5

public static void BeginThreadAffinity()

관리 코드가 현재 물리적 OS 스레드의 ID에 의존하는 명령을 실행하려 함을 호스트에 알립니다.

6

public static void EndCriticalRegion()

스레드 중단이나 처리되지 않은 예외의 영향이 현재 작업으로 제한되는 코드 영역에 진입하려 함을 호스트에 알립니다.

7

public static void EndThreadAffinity()

관리 코드가 현재 물리적 OS 스레드의 ID에 의존하는 명령 실행을 마쳤음을 호스트에 알립니다.

8

public static void FreeNamedDataSlot(string name)

프로세스의 모든 스레드에 대해 이름과 슬롯 간의 연결을 제거합니다. 더 나은 성능을 위해 ThreadStaticAttribute로 표시된 필드를 사용하세요.

9

public static Object GetData(LocalDataStoreSlot slot)

현재 스레드의 현재 도메인 내에서 지정된 슬롯에서 값을 검색합니다. 더 나은 성능을 위해 ThreadStaticAttribute로 표시된 필드를 사용하세요.

10

public static AppDomain GetDomain()

현재 스레드가 실행 중인 현재 도메인을 반환합니다.

11

public static AppDomain GetDomainID()

고유한 애플리케이션 도메인 식별자를 반환합니다.

12

public static LocalDataStoreSlot GetNamedDataSlot(string name)

이름이 있는 데이터 슬롯을 조회합니다. 더 나은 성능을 위해 ThreadStaticAttribute로 표시된 필드를 사용하세요.

13

public void Interrupt()

WaitSleepJoin 스레드 상태인 스레드를 인터럽트합니다.

14

public void Join()

스레드가 종료될 때까지 호출 스레드를 차단하면서 표준 COM 및 SendMessage 펌핑을 계속 수행합니다. 이 메서드에는 다양한 오버로드 형태가 있습니다.

15

public static void MemoryBarrier()

메모리 접근을 동기화합니다. 현재 스레드를 실행하는 프로세서는 MemoryBarrier 호출 이전의 메모리 접근이 이후의 메모리 접근 이후에 실행되도록 명령을 재정렬할 수 없습니다.

16

public static void ResetAbort()

현재 스레드에 요청된 Abort를 취소합니다.

17

public static void SetData(LocalDataStoreSlot slot, Object data)

현재 실행 중인 스레드의 현재 도메인에 대해 지정된 슬롯의 데이터를 설정합니다. 더 나은 성능을 위해 ThreadStaticAttribute로 표시된 필드를 사용하세요.

18

public void Start()

스레드를 시작합니다.

19

public static void Sleep(int millisecondsTimeout)

스레드를 일정 시간 동안 일시 중지합니다.

20

public static void SpinWait(int iterations)

iterations 매개 변수로 정의된 횟수만큼 스레드가 대기하게 합니다.

21

public static byte VolatileRead(ref byte address) 등

필드 값을 읽습니다. 값은 프로세서 수나 프로세서 캐시 상태와 관계없이 컴퓨터의 모든 프로세서가 마지막으로 쓴 값입니다. 다양한 오버로드 형태가 있습니다.

22

public static void VolatileWrite(ref byte address, byte value) 등

필드에 즉시 값을 써서 컴퓨터의 모든 프로세서에서 값이 보이게 합니다. 다양한 오버로드 형태가 있습니다.

23

public static bool Yield()

호출 스레드가 현재 프로세서에서 실행 준비가 된 다른 스레드에 실행을 양보하게 합니다. 운영체제가 양보할 스레드를 선택합니다.

스레드 생성

스레드는 Thread 클래스를 확장하여 생성합니다. 확장된 Thread 클래스는 Start() 메서드를 호출하여 자식 스레드 실행을 시작합니다.

다음 프로그램은 이 개념을 보여줍니다.

Live Demo
using System;
using System.Threading;
namespace MultithreadingApplication {
    class ThreadCreationProgram {
        public static void CallToChildThread() {
            Console.WriteLine("Child thread starts");
        }
        static void Main(string[] args) {
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
            Console.ReadKey();
        }
    }
}

위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.

In Main: Creating the Child thread
Child thread starts

스레드 관리

Thread 클래스는 스레드 관리를 위한 다양한 메서드를 제공합니다.

다음 예제는 특정 시간 동안 스레드를 일시 중지하는 Sleep() 메서드 사용을 보여줍니다.

Live Demo
using System;
using System.Threading;
namespace MultithreadingApplication {
    class ThreadCreationProgram {
        public static void CallToChildThread() {
            Console.WriteLine("Child thread starts");
            // 스레드를 5000밀리초 동안 일시 중지
            int sleepfor = 5000;
            Console.WriteLine("Child Thread Paused for {0} seconds", sleepfor / 1000);
            Thread.Sleep(sleepfor);
            Console.WriteLine("Child thread resumes");
        }
        static void Main(string[] args) {
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
            Console.ReadKey();
        }
    }
}

위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.

In Main: Creating the Child thread
Child thread starts
Child Thread Paused for 5 seconds
Child thread resumes

스레드 종료

Abort() 메서드는 스레드 종료에 사용됩니다.

런타임은 ThreadAbortException을 던져 스레드를 중단합니다. 이 예외는 잡을 수 없으며, 제어는 finally 블록(있는 경우)으로 전달됩니다.

다음 프로그램은 이를 보여줍니다.

Live Demo
using System;
using System.Threading;
namespace MultithreadingApplication {
    class ThreadCreationProgram {
        public static void CallToChildThread() {
            try {
                Console.WriteLine("Child thread starts");
                // 10까지 카운트하는 작업 수행
                for (int counter = 0; counter <= 10; counter++) {
                    Thread.Sleep(500);
                    Console.WriteLine(counter);
                }
                Console.WriteLine("Child Thread Completed");
            } catch (ThreadAbortException e) {
                Console.WriteLine("Thread Abort Exception");
            } finally {
                Console.WriteLine("Couldn't catch the Thread Exception");
            }
        }
        static void Main(string[] args) {
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
            // 메인 스레드를 잠시 중지
            Thread.Sleep(2000);
            // 이제 자식 스레드 중단
            Console.WriteLine("In Main: Aborting the Child thread");
            childThread.Abort();
            Console.ReadKey();
        }
    }
}

위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.

In Main: Creating the Child thread
Child thread starts
0
1
2
In Main: Aborting the Child thread
Thread Abort Exception
Couldn't catch the Thread Exception

C 언어

  1. 마이너 vs 메이저 나사산 직경: 올바른 스크루 크기 선택법
  2. 실: 종류, 역사, 생산, 그리고 품질 관리
  3. Thread vs ZigBee: IoT 엔지니어를 위한 기술적 비교
  4. 적절한 나사 처리제 선택: 신뢰성 향상과 다운타임 감소
  5. C++ 멀티스레딩 마스터하기: 효율적인 동시 프로그래밍
  6. 파이썬 멀티스레드 프로그래밍: 효율적인 동시성 기법 마스터하기
  7. 엣지 컴퓨팅, 업계 승인 명확한 프레임워크 확보
  8. 초고속 백사이드 일루미네이션: 초당 100만 프레임 촬영 실현
  9. 디지털 스레드 풀기: 지멘스 PLM의 스마트 제조 청사진
  10. 나사 절삭 공구(Thread Cutter) 이해: 유형, 용도, 응용