안녕하세요 삽잡이입니다.
이전 시간까지 비동기 대리자를 통해서
우리가 제어할 수 없는... 쓰레드를 경험해봤습니다.
그런데, 이번에는 사용자가
실제로 쓰레드를 생성해보는 시간을 가져보려고합니다.
닷넷에서 제공해주는 Threading 네임 스페이스는
멀티스레드 응용 프로그램을 직접 만들 수 있게 해주는 다양한 타입을 제공해줍니다.
몇가지 특성에 대해서 간략하게 알아보자면,
Interlocked 라는 타입은 원자적인 연산을 지원해줍니다.
그리고 Monitor가 있는데,
해당 타입이 가장 많이 동기화를 수행할 때 사용하는 타입입니다.
Threading 네임 스페이스 중에서도,
Thread 클래스에서는 Sleep 메서드를 많이 사용합니다.
이는 정적 메서드지요.
그리고 인스턴스 수준에서는 IsBackground 인스턴스를 많이 사용합니다.
background라는 것이 나왔으니...
잠시 알아보자면,
이전에는 background, forground 쓰레드를 나누지 않았습니다.
그런데 지금은 나누죠.. 허허...
forground 쓰레드는 해당 쓰레드가 종료하지 않는 한
어플리케이션이 종료되지 않습니다.
즉, APP의 종료에 영향을 주는 쓰레드라는 것입니다.
Main 쓰레드가 종료되더라도 APP이 종료되지 않겠지요.
Background 쓰레드의 경우 내부적으로 동작하는 쓰레드로써
forground 쓰레드와 반대입니다.
실제 쓰레드를 생성해봅시다.
이와 같이 쓰레드 타입 객체를 생성할 수 있습니다.
이전에는 쓰레드를 생성하면
생성과 동시에 쓰레드가 시작이 됬었지요.
그런데, 닷넷에서는 쓰레드 객체 따로, 쓰레드 객체 실행 따로입니다.
자.. 쓰레드 객체를 생성했다면,
쓰레드를 실행하고자하는 명령어 체계를 가져야하는데,
ThreadStart라는 대리자를 통해서 명령어 체계를 가질 수 있는 것입니다.
그리고 이처럼 쓰레드를 생성하게되면,
default 값으로 forground 쓰레드 형식을 가지게 됩니다.
따라서 이녀석이 끝날 때까지 프로그램은 살아있게 됩니다.
만약, Main 쓰레드가 완료됬을때 프로그램을 죽이려면?
backgroundThread.IsBackground를 true로 설정해주면 되겠지요.
이와 같이 설정하게 되면,
Main 쓰레드가 forground 쓰레드가 되기 때문에,
sub 쓰레드인 backgroundThread는 당연히 main 쓰레드 종료시 죽겠지요.
동시성을 사용하기 제외하기 위해서는 'Lock'키워드를 사용할 수 있습니다.
즉, 공유 리소스에 대한 접근을 동기화하는 것이지요.
그런데, 아까는 Monitor를 많이 사용한다고 했는데
앞,뒤 안맞게 뭔 소리일까요...
사실은 Lock 키워드가 내부적으로 Monitor 키워드를 사용하게 됩니다.
즉, 컴파일러가 Monitor의 시작과 끝으로 변환해준다 이겁니다.
참고로, Lock 키워드가 가장 일반적인 원자적 연산에 사용됩니다.
() 괄호는 구분자로써 Lock 토큰이라고 부르지요.
즉, 구분자가 같게 되면 같은 블럭이 되는 것입니다.
이렇게 사용하게 되면, Lock 키워드와 같게 되는 것입니다.
그런데, 왜 Monitor가 아닌 Lock 키워드를 사용할까요?
만약, Monitor를 통해 동기화를 걸어두었는데,
예외가 발생하면 어떻게 될까요?
예외가 발생하던 하지 않던 실행하기 위해서는
finally 블럭을 만들어줘야하는데,
Lock 키워드를 사용하면 자동적으로 위의 예제처럼 만들어줍니다.
즉, Lock 블럭에서 예외가 발생하더라도
Exit는 꼭 호출된다는 것이죠.
따라서, Lock 키워드를 더 많이 사용하는 것입니다.
아무튼..
이처럼 쓰레드를 생성하고 실행할 수 있습니다.
기존에 delegate를 사용했을 때에는
자동적으로 비동기 delegate가 알아서 해줬는데 말입니다.
즉, 함수 만들어두고 쓰레드보러 실행시키라고 했던 것이고,
지금은 쓰레드 객체를 만든 것입니다.
독립적으로 실행할 객체 말입니다.
이때에 독립적으로 각각의 쓰레드 객체가
데이터를 처리하면 동기화가 필요없겠지만,
하나의 공유데이터를 쓰레드 객체들이 접근할 때에는
지금 배운 Lock, Monitor와 같은 키워드를 통해 순서있게 접근시킬 수 있습니다.
그런데 이 키워드들을 다시 설명해보자면,
Monitor 키워드는 독립적으로써
시작할때와 끝할때 따로 따로 구분해줄 수 있습니다.
Lock 키워드는 묶여있지만 말입니다.
즉, 함수 하나로 사용할 수 있는 것이 Lock 키워드라는 것입니다.
그런데, 동기화에 관련하여 아무 코드도 구현할 필요없이
쉽게 동기화 처리를 할 수 있습니다.
바로 '[Synchronization]' 특성을 부여하는 것입니다.
그러면 컨텍스트 바운드 객체로써 다른 컨텍스트에 놓이게 되지요.
그리고 그 컨텍스트에 놓인 객체들은 무조건 동기화한다는 뜻이 되겠지요.
즉, CLR이 검사해서 특정요청을 가졌다는 전제하에
동기화를 수행하겠다는 의미를 갖게 되는 것입니다.
참고로, 특성은 모든 클래스에 정의 되어있는
모든 메서드를 동기화하고자할 때 사용합니다.
따라서, 부분적으로 동기화를 사용하고자할 때에는
키워드를 쓰는것이 훨씬 효율적이겠지요.
이번 시간은 여기까지 하도록 하겠습니다.
이상 삽잡이였습니다!
'삽질의 현장 > - .NET' 카테고리의 다른 글
#081_닷넷(.NET)_.Net Framework 기본 - 파일(File) & 스트림(Stream) (0) | 2015.11.15 |
---|---|
#080_닷넷(.NET)_.Net Framework 기본 - Thread Pool &TPL (0) | 2015.11.15 |
#078_닷넷(.NET)_.Net Framework 기본 - 비동기 대리자(delegate) & 멀티 쓰레드(Multi Thread) (0) | 2015.11.15 |
#077_닷넷(.NET)_.Net Framework 기본 - 객체 컨텍스트 (0) | 2015.11.15 |
#076_닷넷(.NET)_.Net Framework 기본 - 어플리케이션 도메인 (0) | 2015.11.15 |