using System;
using System.Threading;
namespace SeverCore
{
class Program {
static void MainThread()
{
Console.WriteLine("Hello Thread!");
}
static void Main(string[] args)
{
Thread t = new Thread(MainThread);
t.Start();
Console.WriteLine("Hello World!");
}
}
}
C#은 C++과는 다르게 foreground 가 default 이다.
따라서 아래와 같이 쓰레드를 무한 루프로 만든다면 영원히 끝나지 않을 것이다.
namespace SeverCore
{
class Program {
static void MainThread()
{
while(true)
Console.WriteLine("Hello Thread!");
}
static void Main(string[] args)
{
Thread t = new Thread(MainThread);
t.Start();
Console.WriteLine("Hello World!");
}
}
}
쓰레드의 IsBackground = true 설정을 이용하여 Main 함수가 종료하면
쓰레드도 종료하도록 한다.
namespace SeverCore
{
class Program {
static void MainThread()
{
while(true)
Console.WriteLine("Hello Thread!");
}
static void Main(string[] args)
{
Thread t = new Thread(MainThread);
t.IsBackground = true;
t.Start();
Console.WriteLine("Hello World!");
}
}
}
t.Join() 을 넣어 실행 해당 쓰레드가 종료될 때까지 기다리는 함수를 넣을 수도 있다.
namespace SeverCore
{
class Program {
static void MainThread()
{
while(true)
Console.WriteLine("Hello Thread!");
}
static void Main(string[] args)
{
Thread t = new Thread(MainThread);
t.Name = "Test Thread";
t.IsBackground = true;
t.Start();
Console.WriteLine("Waiting for Thread!");
t.Join();
Console.WriteLine("Hello World!");
}
}
}
간단한 동작을 사용하기 위해 쓰레드를 이용하고 싶은 경우에는?
쓰레드는 부담이 클 경우
ThreadPool.QueueUserWorkItem 를 이용한다.
namespace SeverCore
{
class Program
{
static void MainThread(object state)
{
for (int i = 0; i < 5; i++)
Console.WriteLine("Hello Thread!");
}
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(MainThread);
while (true)
{
//main 함수를 계속하기 위함
}
}
}
}
쓰레드 수랑 cpu 코어의 수를 맞춰주는 것이 좋다.
ThreadPool은 최대로 동시에 돌릴 수 있는 쓰레드 수를 제한한다.
그러므로 긴 작업을 할당할 경우 먹통이 될 위험이 있다.
먹통이 되는 경우
namespace SeverCore
{
class Program
{
static void MainThread(object state)
{
for (int i = 0; i < 5; i++)
Console.WriteLine("Hello Thread!");
}
static void Main(string[] args)
{
ThreadPool.SetMinThreads(1, 1);
ThreadPool.SetMaxThreads(5, 5);
for (int i = 0; i < 5; i++)
ThreadPool.QueueUserWorkItem((obj) => { while (true) { } });
ThreadPool.QueueUserWorkItem(MainThread);
while (true)
{
}
}
}
}
해결 방안
해당 작업이 오래 걸릴 것이라는 것을 알려줌.
Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning);
t.Start();
namespace SeverCore
{
class Program
{
static void MainThread(object state)
{
for (int i = 0; i < 5; i++)
Console.WriteLine("Hello Thread!");
}
static void Main(string[] args)
{
ThreadPool.SetMinThreads(1, 1);
ThreadPool.SetMaxThreads(5, 5);
for (int i = 0; i < 5; i++)
{
Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning);
t.Start();
}
ThreadPool.QueueUserWorkItem(MainThread);
while (true)
{ }
}
}
}