728x90
반응형
1. 사전 개념
using System;
using System.Threading;
class Program {
public static void Foo() {
Console.WriteLine("Foo Start");
Thread.Sleep(10000);
Console.WriteLine("Foo End");
}
public static void Main() {
Foo();
}
}
위의 그림과 같이 컴퓨터에는 HDD / SSD와 같은 저장장치와 MEMORY가 있다.
보통 저장장치에 확장자 exe와 같은 것들이 있는데 이러한 것을 통들어 프로그램이라 부른다.
그리고 프로그램을 실행시키게 되면 컴퓨터가 프로그램을 실행시키기 위해 메모리에 올리게 된다.
이렇게 메모리에 올라와 있는 상태를 프로세스라고 한다.
모든 프로그램은 Main함수부터 순차적으로 실행되게 될텐데
프로그램에서 순차적으로 실행하는 실행 흐름을 스레드라고 한다.
기본적으로 스레드는 1개로 만들어지지만
가끔 프로그램을 하다보면 여러곳을 동시 실행하고 싶을 때가 있는데 그럴 경우 스레드를 더 만들면 된다.
위의 그림의 경우 3개의 스레드가 3곳을 동시에 실행해가고 있는 모습이다.
① 스레드(Thread) : 프로그램내(프로세스 내에서)에서의 실행 흐름 단위
2. 핵심 정리
using System;
using System.Threading;
class Program {
public static void Foo() {
Console.WriteLine("Foo Start");
Thread.Sleep(2000);
Console.WriteLine("Foo End");
}
public static void Main() {
Foo(); // 주 스레드가 호출
Console.WriteLine("Main Start");
Thread.Sleep(2000);
Console.WriteLine("Main End");
}
}
위의 코드에서 스레드가 없다고 가정하면 실행 결과는
Foo Start -> Foo End -> Main Start -> Main End 가 될 것이다.
사실 스레드가 있어도 결과는 변함없다. 대신 Start와 End사이에 2초간의 대기시간을 준다.
위의 그림처럼 여러개가 동시에 실행되는 것은 아니고 Main에서 순차적으로 실행되므로
하나의 스레드로 돌고 있는 중인 것이다.
한번에 실행하고 싶다면 스레드를 하나 더 만들어야 한다.
① Thread를 생성하는 방법
=> Thread 객체 생성
=> Thread 클래스의 Start() 메소드 호출
using System;
using System.Threading;
class Program {
public static void Foo() {
Console.WriteLine("Foo Start");
Thread.Sleep(2000);
Console.WriteLine("Foo End");
}
public static void Main() {
// Foo(); // 주 스레드가 호출
Thread t = new Thread(Program.Foo);
t.Start();
Console.WriteLine("Main Start");
Thread.Sleep(2000);
Console.WriteLine("Main End");
}
}
위와 같이 코드를 수정하면 Main과 Foo과 동시에 돌게 된다.
Main, Foo Start가 동시 출력되고 2초 후 Main, Foo가 동시에 종료된다.
3. Thread 클래스
① Thread 생성자
Thread(ThreadStart start);
Thread(ParameterizedThreadStart start);
Thread(Thread start, int maxStackSize);
Thread(ParameterizedThreadStart start, int maxStackSize);
// ----
delegate void ThreadStart();
delegate void ParameterizedThreadStart(object obj);
Thread의 정의로 이동하여 생성자를 살펴보면 위의 1~4번 라인의 생성자 4개를 볼 수 있다.
그 중 ThreadStart를 확인해보면 delegate인데 return이 void고 parameter가 없는 것을 확인할 수 있다.
즉, 생성자로 인자를 줄 때 parameter가 없는 함수가 와야 되는 것이다.
그 다음 ParameterizedThreadStart를 확인해보면 똑같이 delegate에 return이 void이지만 parameter로 obejct를 받는다.
즉, 생성자로 인자를 줄 때 parameter가 object인 함수를 줄 수도있다.
아래에서 예시를 살펴보자.
using System;
using System.Threading;
class Program {
public static void F1() { }
public static void F2(object obj) { }
public static void F3(string s1) { }
public static void F4(string s1, int n) { }
public static void Main() {
Thread t1 = new Thread(F1);
t1.Start();
Thread t2 = new Thread(F2);
t2.Start("hello");
// Thread t3 = new Thread(F3);
// t3.Start("hello");
Thread t3 = new Thread(() => F3("hello"));
t3.Start();
Thread t4 = new Thread(() => F4("hello", 1);
t4.Start();
}
}
먼저 t1-F1 의 경우 인자가 없고 return도 없으므로 바로 인자로 주면 된다.
t2-F2 의 경우 인자가 object이므로 객체를 만든 후 start시점에 인자를 전달하면 된다.
t3-F3 의 경우가 문제인데, 인자로 string을 전달한다.
t2-F2 의 경우와 마찬가지로 작성하면 에러가 나게 된다.
인자로 object를 전달해야 하는데 string을 전달하고 있으므로 에러가 나는 것이다.
이럴때는 람다표현식을 사용해서 해결할 수 있다.
20번 라인의 의미는 새로운 Thread 객체를 만들건데, F3을 수행하겠다는 의미가 아닌
람다표현식을 실행하겠다란 의미가 된다. 그리고 ( ) 는 인자가 없다는 이야기다.
따라서 ThreadStart생성자로 가게 된다.
그리고 거기서 F3을 호출하게 되게 되는 것이다. 따라서 start부분에 인자는 필요 없게 된다.(생성자로 인자를 전달해서)
그래서 F3을 바로 실행하는 형태는 아니고 람다표현식을 통해 F3을 실행시키는 형태이다.
t4-F4의 경우도 위와 같이 람다 표현식으로 전달해주면 된다.
② 인자의 타입이 object가 아니거나, 인자의 개수가 여러 개인 경우
=> 람다 표현식을 사용
728x90
반응형
'프로그래밍 > C#' 카테고리의 다른 글
[C#] Task 클래스 (0) | 2020.05.10 |
---|---|
[C#] 스레드 클래스 멤버 (0) | 2020.05.08 |
[C#] Fluent vs Query (LINQ Fluent vs Query Syntax) (0) | 2020.05.07 |
[C#] LINQ 원리 (0) | 2020.05.07 |
[C#] LINQ 개념 (Language INtegrated Query) (0) | 2020.05.06 |