Microsoft MVP성태의 닷넷 이야기
안녕하세요. c#의 워커스레드에 대해 질문을 드립니다. [링크 복사], [링크+제목 복사]
조회: 1723
글쓴 사람
리세 (licenniezh at naver.com)
홈페이지
첨부 파일
 

안녕하세요. c#의 워커스레드에 대해 질문을 드립니다.
보시면 아시겠지만 도저히 않풀려저 문의를 드립니다.ㅡㅡ;;;

public class SemaPhoreTest1s
    {
        public SemaPhoreTest1s()
        {
            for (int i=1;i<=10;i++)
            {
                int idnums = i;

                Task.Run(()=>TestSemaPhoreSlims("ID:"+ idnums));
              
            }

            Console.WriteLine("MAIN THREAD:"+Thread.CurrentThread.ManagedThreadId);

            Console.ReadLine();

        }

        public async void TestSemaPhoreSlims(string ids)
        {
            int workerThreads, completionPortThreads;

            ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);

            Console.WriteLine("START TestSemaPhoreSlims:ID["+ ids + "] workerThreads>>>" + workerThreads+": times>>>"+DateTime.Now.ToString("HH-mm-ss"));

            Thread.Sleep(5000);
            //await Task.Delay(5000);

         
        }
    }
에서 만약 await Task.Delay(5000); 로 하면 Console.WriteLine("START TestSemaPhoreSlims:ID["+ ids + "]... 부분이 딜레이 없이 찍히는데.
Thread.Sleep(5000);로하면 아래와 같은 로그가 나오고
MAIN THREAD:1
START TestSemaPhoreSlims:ID[ID:2] workerThreads>>>2041: times>>>16-06-43
START TestSemaPhoreSlims:ID[ID:1] workerThreads>>>2041: times>>>16-06-43
START TestSemaPhoreSlims:ID[ID:5] workerThreads>>>2041: times>>>16-06-43
START TestSemaPhoreSlims:ID[ID:4] workerThreads>>>2041: times>>>16-06-43
START TestSemaPhoreSlims:ID[ID:3] workerThreads>>>2041: times>>>16-06-43
START TestSemaPhoreSlims:ID[ID:6] workerThreads>>>2041: times>>>16-06-43
START TestSemaPhoreSlims:ID[ID:7] workerThreads>>>2040: times>>>16-06-44
START TestSemaPhoreSlims:ID[ID:8] workerThreads>>>2039: times>>>16-06-45
START TestSemaPhoreSlims:ID[ID:9] workerThreads>>>2038: times>>>16-06-46
START TestSemaPhoreSlims:ID[ID:10] workerThreads>>>2037: times>>>16-06-47

"START TestSemaPhoreSlims:ID[ID:7] workerThreads>>>2040: times>>>16-06-44"이 부분부터
자꾸 딜레이가 되면서 찍히게 됩니다.
물론 await를 하면 되긴 하는데. 전 이 이유가 정말 궁금합니다.
Thread.Sleep(5000);는 어차피 각각의 task만 sleep하는거 같고 그래도
Console.WriteLine("START TestSemaPhoreSlims:ID["+ ids + "]...는 바로바로 딜레이가 없어야 하는데 딜레이가 생겨서입니다.

질문이 두서없지만 부탁을 드립니다....










[최초 등록일: ]
[최종 수정일: 5/28/2023]


비밀번호

댓글 작성자
 



2023-05-29 11시36분
아래의 글을 참고하세요.

ThreadPool.QueueUserWorkItem의 실행 지연
; https://www.sysnet.pe.kr/2/0/1455
정성태
2023-05-30 10시33분
[리세] 아... 정말 감사드립니다.
ThreadPool.setMinThreads(a,b); 를 조정하니 문제가 해결되었습니다.

근데 한가지 의문이 있습니다. 제 컴의 ThreadPool의 가능한 쓰레드의 수가 2047이라고
나오고 정성태님 말씀 처럼 getMinThreads()는 6개가 나오고 말씀처럼 6개 이후부터 딜레이 현상이 나타납니다.

그럼 혹시 이런 시나리오대로 이해해도 상관이 없는지 말입니다.....

for(in i=0;i<=20;i++) { task 할당 }에서 수식간에 ThreadPool에 task의 살당이 이루어지는데, getMinThreads()의 6개 까지는
각자의 워커쓰레드로 각각 task가 할당이 되어서 딜레이 없이 찍히는데, 6개 이상부터는 각각의 task에 thread.sleep(5000)이 있어서
6개 이상부터는 새로운 워커쓰레드를 가려와서 먼가를 처리하느라 시간이 소요된다???

그리고 이 getMinThreads() 자체를 setMinThreads(a,b)로 조정하면 딜레이가 없다.

그래서 궁금한게. 정말 이겁니다.
제 컴의 ThreadPool의 가능한 쓰레드의 수가 2047이라고 한다는것에서 이 각각의 워커쓰레드(2047갯수의 각각의 것들?)에 어떤
task가 할당될때 이 각각의 task의 자체 작업이 다 끝나야 해당 워커쓰레드가 다른 task의 할당될수 있는 건가요?

예를 들어 2047의 워커 쓰레드 중 하나의 이름을 a worker라고 할때, 이 a worker에 어떤 task가 할당되면
이 a worker는 해당 task의 작업이 모두 완료되거나 끝나야, 다른 task에 할당 되어질수 있는건가요?????

너무 당연한 질문일지 모르지만. 만약 그렇다면 위의 딜레이 현상이 이해가 될것도 같아서 질문을 다시 드립니다.

a worker => task1할당( 각각 sleep(5000) )
b worker => task2할당( 각각 sleep(5000) )
c worker => task3할당( 각각 sleep(5000) )
d worker => task4할당( 각각 sleep(5000) )
e worker => task5할당( 각각 sleep(5000) )
f worker => task6할당( 각각 sleep(5000) )
==== getMinThreads()가 6개이기에 여기서부터 위의 sleep(5000)으로 인해 새로운 먼가를 생성? 해야해서 딜레이 발생 =====
g worker => task7할당( 각각 sleep(5000) )
....
...
..
.

머 이런 느낌이랄까????
[guest]
2023-05-30 11시20분
Environment.ProcessorCount 수만큼 ThreadPool은 기본 스레드를 생성해 두고 있으며 그 수만큼의 작업은 (미리 스레드가 생성돼 있으므로) 빠르게 할당이 됩니다. 그리고, 현재 특정 스레드가 할당된 작업을 처리하는 중이라면 당연히 다른 작업은 받지 못합니다.

그리고, Environment.ProcessorCount를 넘어서 작업이 할당되는 경우에는, 곧바로 새로운 스레드를 증가시키기보다는 약간의 지연 시간을 두고 증가하는 것뿐입니다.

(참고로, 다음부터는 질문의 내용과 연관된 책의 페이지 번호를 함께 기재해 주세요. 이 게시판에서는 책의 내용 이외에는 질문을 받지 않습니다.)
정성태

NoWriterDateCnt.TitleFile(s)