C #에서 스레드 풀을 언제 사용합니까? [닫은]
C #에서 멀티 스레드 프로그래밍을 배우려고 노력 중이며 스레드 풀을 사용하는 것이 가장 좋으며 내 스레드를 만드는 것이 가장 혼란 스럽습니다. 한 책은 작은 작업에만 스레드 풀을 사용하는 것이 좋지만 (그것이 무엇이든간에) 실제 지침을 찾을 수없는 것 같습니다. 이 프로그래밍 결정을 할 때 고려해야 할 사항은 무엇입니까?
지속적인 처리가 필요한 논리적 인 작업이 많고 동시에 수행하려면 pool + scheduler를 사용하십시오.
원격 서버 또는 디스크 액세스에서 자료 다운로드와 같은 IO 관련 작업을 동시에 수행해야하지만 몇 분마다 한 번씩 말해야하는 경우, 고유 한 스레드를 작성하고 완료되면 종료하십시오.
편집 : 몇 가지 고려 사항에 대해 데이터베이스 액세스, 물리 / 시뮬레이션, AI (게임) 및 많은 사용자 정의 작업을 처리하는 가상 시스템에서 실행되는 스크립트 작업에 스레드 풀을 사용합니다.
일반적으로 풀은 프로세서 당 2 개의 스레드 (현재 요즘 4 개)로 구성되지만 필요한 수를 알고있는 경우 원하는 스레드 수를 설정할 수 있습니다.
편집 : 자신의 스레드를 만드는 이유는 컨텍스트 변경 때문입니다 (스레드가 메모리와 함께 프로세스 안팎으로 스왑 해야하는 경우). 쓰레드를 사용하지 않을 때와 같이 쓸모없는 컨텍스트 변경이 있으면, 마치 말 그대로 그대로두면 프로그램 성능이 쉽게 절반으로 떨어질 수 있습니다 (예를 들어 3 개의 휴면 스레드와 2 개의 활성 스레드가 있음). 따라서 다운로드 스레드가 대기 중이면 많은 CPU를 소비하고 실제 응용 프로그램의 캐시를 냉각시킵니다.
다른 언어와 같은 이유로 C #에서 스레드 풀을 사용하는 것이 좋습니다.
실행중인 스레드 수를 제한하거나 스레드를 작성 및 삭제하는 오버 헤드를 원하지 않는 경우 스레드 풀을 사용하십시오.
작은 작업으로 읽는 책은 수명이 짧은 작업을 의미합니다. 1 초 동안 만 실행되는 스레드를 만드는 데 10 초가 걸리면 풀을 사용해야하는 곳입니다 (실제 수치는 무시하고 비율입니다).
그렇지 않으면 단순히 의도 한 작업을 수행하지 않고 스레드를 작성하고 파괴하는 데 많은 시간을 소비합니다.
.Net의 스레드 풀에 대한 요약은 다음과 같습니다. http://blogs.msdn.com/pedram/archive/2007/08/05/dedicated-thread-or-a-threadpool-thread.aspx
게시물에는 스레드 풀을 사용하지 말고 자체 스레드를 대신 시작해야 할 때도 있습니다.
이 무료 전자 책을 읽는 것이 좋습니다. Josephing by Threading in C #
최소한 "시작하기"섹션을 읽으십시오. 전자 책은 훌륭한 소개를 제공하며 풍부한 고급 스레딩 정보도 포함합니다.
스레드 풀 사용 여부를 아는 것은 시작에 불과합니다. 다음으로 요구에 가장 적합한 스레드 풀을 입력하는 방법을 결정해야합니다.
- 작업 병렬 라이브러리 (.NET Framework 4.0)
- ThreadPool.QueueUserWorkItem
- 비동기 대리인
- BackgroundWorker
이 전자 책은이 모든 것을 설명하고 그것들을 언제 사용할 것인지 조언하고 나만의 스레드를 만듭니다.
스레드 풀은 스레드 간의 컨텍스트 전환을 줄 이도록 설계되었습니다. 여러 구성 요소가 실행중인 프로세스를 고려하십시오. 이러한 각 구성 요소는 작업자 스레드를 생성 할 수 있습니다. 프로세스에서 스레드가 많을수록 컨텍스트 전환에 더 많은 시간이 낭비됩니다.
이제 각 구성 요소가 스레드 풀에 항목을 큐에 넣는 경우 컨텍스트 전환 오버 헤드가 훨씬 줄어 듭니다.
스레드 풀은 CPU (또는 CPU 코어)에서 수행되는 작업을 최대화하도록 설계되었습니다. 이것이 기본적으로 스레드 풀이 프로세서 당 여러 스레드를 스핀 업하는 이유입니다.
스레드 풀을 사용하지 않으려는 상황이 있습니다. I / O를 기다리거나 이벤트를 기다리는 경우 해당 스레드 풀 스레드를 묶어 다른 사람이 사용할 수 없습니다. 장기 실행 작업을 구성하는 것이 주관적이지만 동일한 아이디어가 장기 실행 작업에 적용됩니다.
Pax Diablo도 좋은 지적입니다. 실을 회전시키는 것은 자유롭지 않습니다. 시간이 걸리고 스택 공간을 위해 추가 메모리를 소비합니다. 스레드 풀은 스레드를 재사용하여이 비용을 상각합니다.
참고 : 스레드 풀 스레드를 사용하여 데이터를 다운로드하거나 디스크 I / O를 수행하는 방법에 대해 질문했습니다. 이를 위해 스레드 풀 스레드를 사용해서는 안됩니다 (위에 설명한 이유로). 대신 비동기 I / O (일명 BeginXX 및 EndXX 메소드)를 사용하십시오. A의 FileStream
그 것 BeginRead
하고 EndRead
. 들어 HttpWebRequest
있을 것이라고 BeginGetResponse
하고 EndGetResponse
. 사용하기가 더 복잡하지만 멀티 스레드 I / O를 수행하는 올바른 방법입니다.
스레드 기아가 발생하기 쉽기 때문에 처리 과정에서 중요하거나 가변적이거나 알려지지 않은 부분을 차단할 수있는 작업에 대해서는 .NET 스레드 풀을주의하십시오. 스레드 작업에 대해 많은 논리적 추상화를 제공하는 .NET 병렬 확장 사용을 고려하십시오. ThreadPool에서 개선되어야 할 새로운 스케줄러도 포함되어 있습니다. 여기를 참조 하십시오
소규모 작업에만 스레드 풀을 사용하는 한 가지 이유는 제한된 수의 스레드 풀 스레드가 있기 때문입니다. 하나를 오랫동안 사용하면 해당 스레드가 다른 코드에서 사용되지 않습니다. 이 문제가 여러 번 발생하면 스레드 풀이 모두 소모 될 수 있습니다.
스레드 풀을 사용하면 미묘한 영향을 줄 수 있습니다. 예를 들어 일부 .NET 타이머는 스레드 풀 스레드를 사용하며 실행되지 않습니다.
응용 프로그램의 전체 수명과 같이 오랜 시간 동안 지속되는 백그라운드 작업이있는 경우 자체 스레드를 만드는 것이 합리적입니다. 스레드에서 수행해야하는 짧은 작업이있는 경우 스레드 풀링을 사용하십시오.
많은 스레드를 작성하는 응용 프로그램에서는 스레드 작성의 오버 헤드가 상당히 커집니다. 스레드 풀을 사용하면 스레드가 한 번 작성되어 재사용되므로 스레드 작성 오버 헤드가 발생하지 않습니다.
내가 작업 한 응용 프로그램에서 스레드를 만드는 것에서 짧은 수명의 스레드에 대한 스레드 풀을 사용하는 것으로 변경하면 실제로 응용 프로그램의 완성에 도움이되었습니다.
동시 실행 단위로 최고의 성능을 얻으려면 시작시 스레드 객체 풀이 생성되고 차단 (이전 일시 중단)으로 이동하여 컨텍스트 실행 대기 (표준 인터페이스가 구현 된 객체) 인 자체 스레드 풀을 작성하십시오. 귀하의 코드).
Tasks vs. Threads vs. .NET ThreadPool에 대한 많은 기사가 실제로 성능을 결정하는 데 필요한 것을 제공하지 못합니다. 그러나 그것들을 비교하면 스레드가 승리하고 특히 스레드 풀이 나옵니다. CPU 전체에 가장 잘 분산되어 더 빨리 시작됩니다.
논의해야 할 것은 Windows의 주요 실행 단위 (Windows 10 포함)가 스레드이며 OS 컨텍스트 전환 오버 헤드가 무시할 수 있다는 사실입니다. 간단히 말해서, 기사가 컨텍스트 전환을 저장하여 더 높은 성능을 요구하는지 또는 더 나은 CPU 사용을 요구하는지에 관계없이 이러한 기사 중 다수에 대한 확실한 증거를 찾을 수 없었습니다.
이제 약간의 사실감이 있습니다.
우리 대부분은 응용 프로그램이 결정론적일 필요가 없으며, 대부분 운영 체제 개발과 함께 제공되는 스레드에 대한 노크 배경이 없습니다. 위에서 쓴 것은 초보자를위한 것이 아닙니다.
가장 중요한 것은 토론하기가 프로그래밍하기 쉬운 것입니다.
If you create your own thread pool, you’ll have a bit of writing to do as you’ll need to be concerned with tracking execution status, how to simulate suspend and resume, and how to cancel execution – including in an application-wide shut down. You might also have to be concerned with whether you want to dynamically grow your pool and also what capacity limitation your pool will have. I can write such a framework in an hour but that is because I’ve done it so many times.
Perhaps the easiest way to write an execution unit is to use a Task. The beauty of a Task is that you can create one and kick it off in-line in your code (though caution may be warranted). You can pass a cancellation token to handle when you want to cancel the Task. Also, it uses the promise approach to chaining events, and you can have it return a specific type of value. Moreover, with async and await, more options exist and your code will be more portable.
In essence, it is important to understand the pros and cons with Tasks vs. Threads vs. the .NET ThreadPool. If I need high performance, I am going to use threads, and I prefer using my own pool.
An easy way to compare is start up 512 Threads, 512 Tasks, and 512 ThreadPool threads. You’ll find a delay in the beginning with Threads (hence, why write a thread pool), but all 512 Threads will be running in a few seconds while Tasks and .NET ThreadPool threads take up to a few minutes to all start.
Below are the results of such a test (i5 quad core with 16 GB of RAM), giving each 30 seconds to run. The code executed performs simple file I/O on an SSD drive.
Thread pools are great when you have more tasks to process than available threads.
You can add all the tasks to a thread pool and specify the maximum number of threads that can run at a certain time.
Check out this page on MSDN: http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80).aspx
Always use a thread pool if you can, work at the highest level of abstraction possible. Thread pools hide creating and destroying threads for you, this is usually a good thing!
Most of the time you can use the pool as you avoid the expensive process of creating the thread.
However in some scenarios you may want to create a thread. For example if you are not the only one using the thread pool and the thread you create is long-lived (to avoid consuming shared resources) or for example if you want to control the stacksize of the thread.
Don't forget to investigate the Background worker.
I find for a lot of situations, it gives me just what i want without the heavy lifting.
Cheers.
I usually use the Threadpool whenever I need to just do something on another thread and don't really care when it runs or ends. Something like logging or maybe even background downloading a file (though there are better ways to do that async-style). I use my own thread when I need more control. Also what I've found is using a Threadsafe queue (hack your own) to store "command objects" is nice when I have multiple commands that I need to work on in >1 thread. So you'd may split up an Xml file and put each element in a queue and then have multiple threads working on doing some processing on these elements. I wrote such a queue way back in uni (VB.net!) that I've converted to C#. I've included it below for no particular reason (this code might contain some errors).
using System.Collections.Generic;
using System.Threading;
namespace ThreadSafeQueue {
public class ThreadSafeQueue<T> {
private Queue<T> _queue;
public ThreadSafeQueue() {
_queue = new Queue<T>();
}
public void EnqueueSafe(T item) {
lock ( this ) {
_queue.Enqueue(item);
if ( _queue.Count >= 1 )
Monitor.Pulse(this);
}
}
public T DequeueSafe() {
lock ( this ) {
while ( _queue.Count <= 0 )
Monitor.Wait(this);
return this.DeEnqueueUnblock();
}
}
private T DeEnqueueUnblock() {
return _queue.Dequeue();
}
}
}
I wanted a thread pool to distribute work across cores with as little latency as possible, and that didn't have to play well with other applications. I found that the .NET thread pool performance wasn't as good as it could be. I knew I wanted one thread per core, so I wrote my own thread pool substitute class. The code is provided as an answer to another StackOverflow question over here.
As to the original question, the thread pool is useful for breaking repetitive computations up into parts that can be executed in parallel (assuming they can be executed in parallel without changing the outcome). Manual thread management is useful for tasks like UI and IO.
참고URL : https://stackoverflow.com/questions/145304/when-to-use-thread-pool-in-c
'development' 카테고리의 다른 글
File.separator 대 FileSystem.getSeparator () 대 System.getProperty (“file.separator”)? (0) | 2020.07.08 |
---|---|
Github Windows '이 분기를 동기화하지 못했습니다' (0) | 2020.07.08 |
Entity Framework 코드의 고유 제약 조건 (0) | 2020.07.08 |
CMake : 단위 테스트를 사용한 프로젝트 구조 (0) | 2020.07.08 |
jQuery 유효성 검사 플러그인을 사용하여 라디오 버튼 그룹의 유효성 검사 (0) | 2020.07.08 |