레이블이 Thread인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Thread인 게시물을 표시합니다. 모든 게시물 표시

2022년 2월 25일 금요일

[교육동영상]C# 쓰레드(Thread), AutoResetEvent, ManualResetEvent, WaitOne, Set, Reset, C#학원, 닷넷학원, C#교육, WPF교육, WPF학원

 [교육동영상]C# 쓰레드(Thread), AutoResetEvent, ManualResetEvent, WaitOne, Set, Reset, C#학원, 닷넷학원, C#교육, WPF교육, WPF학원


https://www.youtube.com/watch?v=D0siTPkCx3M&list=PLxU-iZCqT52DJyR6gqJy0MCL8RiTVXdos&index=30 


http://ojc.asia/bbs/board.php?bo_table=LecCsharp&wr_id=427 


[동영상]C# 쓰레드(Thread), AutoResetEvent, ManualResetEvent, WaitOne, Set, Reset

[동영상]C# 쓰레드(Thread), AutoResetEvent, ManualResetEvent, WaitOne, Set, ResetC# ThreadAutoResetEvent, ManualResetEventWaitOne, Set, ResetC# 멀티 쓰레드(AutoResetEvent, ManualResetEvent)System.Threading.AutoRe…

ojc.asia

https://www.youtube.com/watch?v=0W2_2lKib-I&list=PLxU-iZCqT52DJyR6gqJy0MCL8RiTVXdos&index=29 



C# Thread

AutoResetEvent, ManualResetEvent

WaitOne, Set, Reset







 C# 멀티 쓰레드(AutoResetEvent, ManualResetEvent)


System.Threading.AutoResetEvent, System.Threading.ManualResetEvent는 WaitOne으로 대기중인 쓰레드에게 신호를 보내 대기중인 여러 쓰레드에서 하나의 쓰레드만 실행을 허용하고다른 쓰레드들은 기다리게 할 수 있다. 마치 건널목의 차단기와 같이 차들이 WaitOne으로 대기하고, Set 신호를 보내면 차단기가 올라가고, 차가 통과 후  다시 Reset 신호를 보내면 차단기가 내려가는 구조를 가진다.




하나의 쓰레드가 AutoResetEvent 객체의 WaitOne() 메소드를 호출하여 대기하고 있다가 다른 쓰레드에서 이 AutoResetEvent, ManualResetEvent의 Set() 메소드를 호출해주면 대기 상태를 해제하고 계속해서 다음 문장을 실행할 수 있는데, 두 클래스의 차이는 AutoResetEvent는 자동으로, ManualResetEvent는 수동으로 Reset 한다. 



AutoResetEvent는 차단기가 올라간 후 쓰레드 하나 실행 후 자동으로 다시 차단기가 다시 내려오고, ManualResetEvent는 자동으로 내려오지 않아 모든 쓰레드가 실행을 하게된다.  그러므로 WaitOne의 상태가 Set으로 풀린 이후 다시 차단기를 내리는 Reset을 천천히 수행하려면 ManualResetEvent 클래스를 사용하면 된다. 





두 클래스의 생성자에 인자를 주면서 생성하는데 true이면 차단기가 올라간 상태, false이면 차단기가 내려간 상태에서 시작한다. 두 클래스의 차이점은 WaitOne의 상태가 Set으로 풀린 이후 Reset을 수동으로 하느냐 자동으로 하느냐에 있다



ManualResetEvent는 하나의 쓰레드만 통과시키고 닫는 AutoResetEvent와 달리 한번 열리면 대기중이던 모든 쓰레드를 실행하게 하고 코드에서 수동으로 Reset()을 호출하여 문을 닫고 이후 도착한 쓰레드들을 다시 대기 하도록 한다.


using System;

using System.Threading;


public class ThreadTest2

{

    bool sleep = false;


    //차단기가 내려간 상태

    static AutoResetEvent autoEvent = new AutoResetEvent(false);


    public void FirstWork()

    {

        for (int i = 0; i < 10; i++)

        {

            Thread.Sleep(1000);

            Console.WriteLine(Thread.CurrentThread.Name + " : {0}", i);

            if (i == 5)

            {

                sleep = true;

                Console.WriteLine("");

                Console.WriteLine(Thread.CurrentThread.Name + " Thread 쉼...");

                autoEvent.WaitOne();

            }

        }

    }

    public static void Main()

    {

        ThreadTest2 t = new ThreadTest2();

        Thread first = new Thread(new ThreadStart(t.FirstWork));

        first.Name = "First";

        Thread second = new Thread(new ThreadStart(t.FirstWork));

        second.Name = "Second";

        first.Start();  second.Start();        

        while (t.sleep == false) { }

        Console.WriteLine("2초후 Thread 깨웁니다.");

        Thread.Sleep(2000);

        autoEvent.Set();  // 차단기 올림, first, second중 하나만 깸

    }

}



Second : 0

First : 0

First : 1

Second : 1

First : 2

Second : 2

Second : 3

First : 3

First : 4

Second : 4

Second : 5


Second Thread 쉼...

2초후 Thread 깨웁니다.

First : 5


First Thread 쉼...

Second : 6

Second : 7

Second : 8

Second : 9



AutoResetEvent는 자동으로 Reset되어 차단기가 내려와 처음 쓰레드 하나만 실행된다.            

ManualResetEvent는 자동으로 차단되지 않아 차단기는 계속열려있다. 그래서 모든 쓰레드가 통과하여 실행된다.

using System;

using System.Threading;


public class ThreadTest2

{

    bool sleep = false;


    //차단기가 내려간 상태

    static ManualResetEvent autoEvent = new ManualResetEvent(false);


    public void FirstWork()

    {

        for (int i = 0; i < 10; i++)

        {

            Thread.Sleep(1000);

            Console.WriteLine(Thread.CurrentThread.Name + " : {0}", i);

            if (i == 5)

            {

                sleep = true;

                Console.WriteLine("");

                Console.WriteLine(Thread.CurrentThread.Name + " Thread 쉼...");

                autoEvent.WaitOne();

            }

        }

    }

    public static void Main()

    {

        ThreadTest2 t = new ThreadTest2();

        Thread first = new Thread(new ThreadStart(t.FirstWork));

        first.Name = "First";

        Thread second = new Thread(new ThreadStart(t.FirstWork));

        second.Name = "Second";

        first.Start();  second.Start();        

        while (t.sleep == false) { }

        Console.WriteLine("2초후 Thread 깨웁니다.");

        Thread.Sleep(2000);

        autoEvent.Set();  // 차단기 올림, first, second중 하나만 깸

    }

}


Second : 0

First : 0

Second : 1

First : 1

First : 2

Second : 2

First : 3

Second : 3

First : 4

Second : 4

Second : 5


Second Thread 쉼...

2초후 Thread 깨웁니다.

First : 5


First Thread 쉼...

First : 6

Second : 6

First : 7

Second : 7

First : 8

Second : 8

First : 9

Second : 9



 

#쓰레드, #Thread, #AutoResetEvent, #ManualResetEvent, #WaitOne, #Set, #Reset, #시샵교육, #닷넷교육, #시샵동영상, #닷넷동영상, 쓰레드, Thread, AutoResetEvent, ManualResetEvent, WaitOne, Set, #Reset, 시샵교육, 닷넷교육, 시샵동영상, 닷넷동영상,  

C# Thread Interrupt, Abort를 이용한 쓰레드 종료

 

http://ojc.asia/bbs/board.php?bo_table=LecCsharp&wr_id=426 


(동영상)C# 쓰레드(Thread) Interrupt, Abort를 이용한 쓰레드 종료

(동영상)C# 쓰레드(Thread) Interrupt, Abort를 이용한 쓰레드 종료C# ThreadInterrupt, Abort를 이용한 쓰레드 종료C# 멀티 쓰레드(쓰레드 종료방법)쓰레드는 할일을 마치고 수명이 다해 스스로 종료하는것이

ojc.asia


C# Thread

Interrupt, Abort를 이용한 쓰레드 종료







C# 멀티 쓰레드(쓰레드 종료방법)



쓰레드는 할일을 마치고 수명이 다해 스스로 종료하는것이 좋지만 부득이 강제로 종료해야 하는 경우가 있다.


종료하는 방법은 강제종료를 위한 Abort,  종료시킬 쓰레드에 Interrupt를 걸어서 그 쓰레드가 Wait, Sleep, Join 상태(이때 쓰레드 상태는 ThreadState.WaitSleepJoin.)가 되면 ThreadInterruptedException이 발생하므로 catch 절에서 예외를 받아서 쓰레드를 종료하면 된다. 



Thread.Interrupt 메소드 : 쓰레드가 동작중인 상태를 피해서 WaitSleepJoin 스레드 상태에 들어갔을 때  ThreadInterruptedException을 던져 예외처리부에서 쓰레드를 중지시                                  킴.

쓰레드가 WaitSleepJoin 상태일 때 : 즉시 ThreadInterruptedException 발생
쓰레드가 Running 상태일 때 : ThreadInterruptedException을 예약, WaitSleepJoin일때 ThreadInterruptedException 발생

Thread.Abort 메소드 :쓰레드를 강제로 종료하는데 프로세스 자신이나 시스템에 영향이 없는 경우에 사용하면 되지만 가능한 사용안하는 것이 좋다.



using System.Threading;

using System;

 

namespace ThreadInterrupt

{

    class Program

    {

        public static Thread sleeperThread;

 

        public static void Main(string[] args)

        {

            sleeperThread = new Thread(new ThreadStart(ThreadToSleep));

            sleeperThread.Start();

            sleeperThread.Interrupt();

        }

        private static void ThreadToSleep()

        {

            int i = 0;

            while (true)

            {

                Console.WriteLine("[Sleeper : " + i++ + "]");

                if (i == 9)

                {

                    try

                    {

                        Console.WriteLine("i가 9가 되어 1초쉼...");

                        Thread.Sleep(1000);

                    }

                    catch (ThreadInterruptedException e)

                    {

                        Console.WriteLine("ThreadInterruptedException ...");

                        Environment.Exit(0);

                    }

                }

            }

        }

    }

 

[결과]

[Sleeper : 0]

[Sleeper : 1]

[Sleeper : 2]

[Sleeper : 3]

[Sleeper : 4]

[Sleeper : 5]

[Sleeper : 6]

[Sleeper : 7]

[Sleeper : 8]

i가 9가 되어 1초쉼...

ThreadInterruptedException …



[Thread.Abort예제]

using System;

using System.Threading;

public class Example

{

    public void Work()

    {

        for (char i = 'A'; i < 'Z'; i++)

        {

            Console.WriteLine(i);

            Thread.Sleep(1000);

        }

    }

}

public class Test

{

    public static void Main()

    {

        Example exam = new Example();

        Thread x = new Thread(new ThreadStart(exam.Work));

        Thread y = new Thread(new ThreadStart(exam.Work));


        x.Start();

        y.Start();

        Thread.Sleep(3000);

        try

        {

            x.Abort();

            y.Abort();

        }

        catch (ThreadAbortException except)

        {

            Console.WriteLine(except.ToString());

        }

        Console.WriteLine("Bye Bye!!");

    }

}




#쓰레드, #Thread, #Interrupt, #Abort, #쓰레드종료, #스레드종료, #닷넷쓰레드, #시샵스레드, #시샵교육, #닷넷교육, #쓰레드Abort, #쓰레드Interrupt, 쓰레드, Thread, Interrupt, Abort, 쓰레드종료, 스레드종료, 닷넷쓰레드, 시샵스레드, 시샵교육, 닷넷교육, 쓰레드Abort, 쓰레드Interrupt,  

2022년 2월 24일 목요일

[동영상]C# 스레드(Thread),HelloWorld,ThreadStart,ParameterizedThreadStart

 

[동영상]C# 스레드(Thread),HelloWorld,ThreadStart,ParameterizedThreadStart 

[동영상]C# 스레드(Thread),HelloWorld,ThreadStart,ParameterizedThreadStart 




C# Thread

HelloWorld


ThreadStart

ParameterizedThreadStart







C# 스레드(Thread)


  • 스레드는 하나의 프로세스(실행 중인 프로그램) 내에 존재하는 순차적인 제어의 흐름을 두기 위해 사용한다. 즉 프로세스는 하나 이상의 스레드로 이루어 진다.


  • 각 스레드는 코드, 데이터, 힙 영역은 공유하며, Stack Frame은 별도로 할당되는데 이를 Thread Stack이라하며 Thread Stack은 메소드 단위로 분리되어 할당되며 실행이 끝나면 Stack Frame은 사라진다. 


  • 멀티 스레드가 제대로 동작하기 위해서는 CPU가 여러 개 있어야 한다. 단일 CPU를 사용하게 되면 CPU는 한 번에 하나의 스레드를 사용한다. 만약 멀티 스레드로 프로그램이 실행되는 경우라면 CPU의 사용 시간을 나누어서 각각의 스레드에게 주기 때문에 단일 쓰레드와 별차이가 없다.


  • C#에서 스레드를 만들기 위해서는 기 정의된 Thread 클래스와 ThreadStart, ParameterizedThreadStart 델리게이트를 이용하면 된다. 


public delegate void ParameterizedThreadStart(object obj);

한 개의 파라미터를 object 형식으로 전달하기 때문에 여러 개의 파라미터를 전달하기 위해서는 클래스나 구조체를 만들거나 배열 등을 이용하여 전달할 수 있다. 파라미터 전달은 Thread.Start() 메소드를 호출할 때 전달한다. 


public delegate void ThreadStart();

스레드가 실행시킬 메소드가 파라미터를 받아들이지 않는 형태이며, ThreadStart를 이용해 파라미터를 전달하는 방법은 ThreadStart 델리게이트가 처다보는 메소드는 파라미터를 받아들이지 않으므로 그 메소드 안에서 다른 메소드를 호출하면서 파라미터를 전달할 수 있다.


  • C#에서 스레드를 위한 클래스들은 System.Threading 네임스페이스 안에 정의되어 있다.



[실습]

1부터 50까지의 합을 5개의 쓰레드에 나누어서 실행하고자 한다. 

첫번째 쓰레드는 1~10 까지의 합을, 두번째 쓰레드는 11~20 까지의 합을.... 다섯번째 쓰레드는 

41~50 사이의 합을 구하는데 아래 두 방법으로 프로그램을 작성하세요. 


- ParameterizedThreadStart 델리게이트를 이용하여 작성하세요. 

- ThreadStart 델리게이트를 이용하여 작성하세요


1. ParameterizedThreadStart 델리게이트를 이용하여 작성


using System;

using System.Threading;

namespace ConsoleApplication2

{

    class Program

    {

        static int mysum = 0;

        static void DoSomething(object n)

        {

            int sum = 0;

            int[] number = (int[])n;

            for (int i = number[0]; i <= number[1]; i++)

            {

                sum += i;

            }

            mysum += sum;

        }

        static void Main(string[] args)

        {

            Thread t1 = new Thread(new ParameterizedThreadStart(DoSomething));

            Thread t2 = new Thread(new ParameterizedThreadStart(DoSomething));


            Thread t3 = new Thread(new ParameterizedThreadStart(DoSomething));


            Thread t4 = new Thread(new ParameterizedThreadStart(DoSomething));

            Thread t5 = new Thread(new ParameterizedThreadStart(DoSomething));

            


            t1.Start(new int[] { 1, 10 });             t2.Start(new int[] { 11, 20 });

            t3.Start(new int[] { 21, 30 });            t4.Start(new int[] { 31, 40 });

            t5.Start(new int[] { 41, 50 });

            

            t1.Join();   t2.Join();    t3.Join();     t4.Join();       t5.Join();


            Console.Write("1부터50까지의 합은{0}::", mysum);

        }

    }

}



2. ThreadStart 델리게이트를 이용하여 작성


using System;

using System.Threading;


namespace ConsoleApplication3

{

    class Program

    {

        static int mysum = 0;

        static void Sum(object n)

        {

            int sum = 0;

            int[] number = (int[])n;

            for (int i = number[0]; i <= number[1]; i++)

            {

                sum += i;

            }

            mysum += sum;

        }


        static void Main(string[] args)

        {            

            Thread t1 = new Thread(new ThreadStart(() => Sum(new int[] { 1, 10 })));

            Thread t2 = new Thread(new ThreadStart(() => Sum(new int[] { 11, 20 })));


            Thread t3 = new Thread(new ThreadStart(() => Sum(new int[] { 21, 30 })));


            Thread t4 = new Thread(new ThreadStart(() => Sum(new int[] { 31, 40 })));

            Thread t5 = new Thread(new ThreadStart(() => Sum(new int[] { 41, 50 })));

            


            t1.Start(); t2.Start(); t3.Start(); t4.Start(); t5.Start();

            t1.Join(); t2.Join(); t3.Join(); t4.Join(); t5.Join();


            Console.WriteLine(mysum);


        }

    }

}




#시샵동영상, #스레드, #Thread, #HelloWorld, #ThreadStart,#ParameterizedThreadStart, #닷넷쓰레드, #쓰레드, #닷넷동영상, #닷넷교육, #시샵교육, 시샵동영상, 스레드, Thread, HelloWorld, ThreadStart,ParameterizedThreadStart, 닷넷쓰레드, 쓰레드, 닷넷동영상, 닷넷교육, 시샵교육, 
 

 #시샵동영상#스레드#Thread#HelloWorld#ThreadStart#ParameterizedThreadStart#닷넷쓰레드#쓰레드#닷넷동영상#닷넷교육#시샵교육시샵동영상스레드ThreadHelloWorldThreadStartParameterizedThreadStart닷넷쓰레드쓰레드닷넷동영상닷넷교육시샵교육,

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...