2011-07-05 7 views
4

그래서 멀티 스레딩 나는 몇 가지 질문을 제기 작은 프로그램을 구축하고 내가 어떤 도움 :) 여기내가의 기초를 이해하기 위해 노력하고있어

감사 할 것

class Program 
{ 
    public static int count; 
    public static int max; 
    static void Main(string[] args) 
    { 
     int t = 0; 
     DateTime Result; 
     Console.WriteLine("Enter Max Number : "); 
     max = int.Parse(Console.ReadLine()); 
     Console.WriteLine("Enter Thread Number : "); 
     t = int.Parse(Console.ReadLine()); 

     count = 0; 

     Result = DateTime.Now; 
     List<Thread> MyThreads = new List<Thread>(); 
     for (int i = 1; i < 31; i++) 
     { 
      Thread Temp = new Thread(print); 
      Temp.Name = i.ToString(); 
      MyThreads.Add(Temp); 
     } 

     foreach (Thread th in MyThreads) 
      th.Start(); 

     while (count < max) 
     { 
     } 

     Console.WriteLine("Finish , Took : " + (DateTime.Now - Result).ToString() + " With : " + t + " Threads."); 
     Console.ReadLine(); 
    } 

    public static void print() 
    { 
     while (count < max) 
     { 
      Console.WriteLine(Thread.CurrentThread.Name + " - " + count.ToString()); 
      count++; 
     } 
    } 
} 

나는 몇 가지 테스트를 실행하여이 확인 : 작은 프로그램입니다

내가 최대 수 (100)를 만든, 그리고 가장 빠른 실행 시간이 80 % 더 빠른 2 개 스레드 것으로 보인다 10 개의 스레드가있는 시간보다

질문 :

1) 스레드 4-10도 한 번 인쇄되지 않습니다, 어떻게 할 수 있습니까?

2) 더 많은 스레드가 더 빠르지 않아야합니까?

나는 최대 숫자 10000을 만들고 인쇄를 사용하지 않습니다.

이 구성을 사용하면 5 개의 스레드가 가장 빠른 것 같습니다.

왜 첫 번째 확인에 비해 변경이 있습니까?

또한이 구성 (인쇄 사용)에서는 모든 스레드가 몇 번 인쇄됩니다. 몇 개의 스레드 만 인쇄되는 첫 번째 실행과 다른 이유는 무엇입니까?

모든 스레드를 하나씩 인쇄하는 방법이 있습니까? 한 줄이나 그런 식으로?

는 당신의 도움을 주셔서 대단히 감사합니다 :)

+1

스레드를 직접 사용하지 마십시오. 반 직관적 인 것처럼 보일지 모르지만 나를 믿으십시오 : 그들은 당신을 미치게 할 것입니다. 내가 당신이라면 C#의 TPL (Task Parallel Library)을 살펴볼 것입니다. –

+0

[동기화] (http://en.wikipedia.org/wiki/Synchronization_%28computer_science%29)에 대한 간략한 개요. – ChaosPandion

+3

이러한 종류의 테스트는 성능 문제를 이해하는 데 적합하지 않습니다. 독서를 많이해야합니다. –

답변

0

귀하의 인쇄 기능은 스레드에서 멀리 안전, 4-10가 인쇄되지 않는 이유입니다. 모든 스레드는 동일한 최대 및 개수 변수를 공유합니다.

왜 스레드가 더 느려지는 이유는 프로세서가 각 스레드간에 포커스를 변경할 때마다 상태가 변경 될 가능성이 높기 때문입니다.

또한 많은 스레드를 만들 때 시스템은 새로운 스레드를 할당해야합니다. 대부분의 경우 시스템 관리 스레드 풀에서 가져온 것처럼 작업을 대신 사용하는 것이 좋습니다. 따라서 반드시 할당 할 필요는 없습니다. 별개의 새 스레드를 만드는 것은 비용이 많이 듭니다. http://msdn.microsoft.com/en-us/library/aa645740(VS.71).aspx

7

귀하의 코드가 확실히 스레딩의 세계로 첫 번째 단계이며, 당신은 단지 두통 (대부분의) 처음 경험했습니다

여기 어쨌든보세요! 시작하려면

, static 스레드 사이의 변수에 당신을 가능하게 할 수있다, 그러나 그것은 스레드 안전 방식으로 그렇게하지 않습니다. 즉, count < max 표현식과 count++의 최신 또는 스레드 사이의 효과적인 보호가 보장되지 않습니다.max가 (내 8 프로세서 워크 스테이션에서, 4 t 세트) 10 때 프로그램의 출력 봐 :

T0 - 0 
T0 - 1 
T0 - 2 
T0 - 3 
T1 - 0 // wait T1 got count = 0 too! 
T2 - 1 // and T2 got count = 1 too! 
T2 - 6 
T2 - 7 
T2 - 8 
T2 - 9 
T0 - 4 
T3 - 1 // and T3 got count = 1 too! 
T1 - 5 

를 인쇄하는 각 스레드에 대한 질문에 하나씩, 난 당신을 가정 count에 대한 액세스를 조정하려고합니다. 이를 동기화 프리미티브 (예 : C#의 lock 문)로 수행 할 수 있습니다.

static object countLock = new object(); 

public static void printWithLock() 
{ 
    // loop forever 
    while(true) 
    { 
     // protect access to count using a static object 
     // now only 1 thread can use 'count' at a time 
     lock (countLock) 
     { 
      if (count >= max) return; 

      Console.WriteLine(Thread.CurrentThread.Name + " - " + count.ToString()); 
      count++; 
     } 
    } 
} 

이 간단한 수정 프로그램이 논리적으로 정확하게, 또한 느린 : 여기에만 max 증가를 보장합니다 코드에 순진 수정이 발생할 수 있습니다. 샘플에 새로운 문제가 발생했습니다 : 잠금 경합. 모든 스레드는 이제 countLock에 액세스하기 위해 경쟁하고 있습니다. 우리는 프로그램의 스레드를 안전하게 만들었지 만 병렬 처리의 이점은 없습니다!

스레딩 및 병렬 처리가 특히 쉽지는 않지만 고맙게도 .Net의 최신 버전은 Task Parallel Library (TPL)Parallel LINQ (PLINQ)과 함께 제공됩니다.

라이브러리의 장점은 현재의 코드를 변환하는 것이 얼마나 쉬운 :

var sw = new Stopwatch(); 

sw.Start(); 
Enumerable.Range(0, max) 
      .AsParallel() 
      .ForAll(number => 
       Console.WriteLine("T{0}: {1}", 
           Thread.CurrentThread.ManagedThreadId, 
           number)); 

Console.WriteLine("{0} ms elapsed", sw.ElapsedMilliseconds); 

// Sample output from max = 10 
// 
// T9: 3 
// T9: 4 
// T9: 5 
// T9: 6 
// T9: 7 
// T9: 8 
// T9: 9 
// T8: 1 
// T7: 2 
// T1: 0 
// 30 ms elapsed 

출력은 위의 스레딩은 새로운 사용자를위한 "예상치 못한 결과"생산 왜 재미있는 그림이다. 스레드가 병렬로 실행되면 다른 시점에 코드 조각을 완료하거나 하나의 스레드가 다른 스레드보다 빠를 수 있습니다. 당신은 스레딩에 대해 정말로 알지 못합니다! carefuly

+0

+1 처음 뵙겠습니다. –

+0

+1 상세하고 유익한 정보! –

0

봐 :

t = int.Parse(Console.ReadLine()); 

    count = 0; 

    Result = DateTime.Now; 
    List<Thread> MyThreads = new List<Thread>(); 
    for (int i = 1; i < 31; i++) 
    { 
     Thread Temp = new Thread(print); 
     Temp.Name = i.ToString(); 
     MyThreads.Add(Temp); 
    } 

난 당신이 변수 t (내가 < 31)를 놓쳤다 생각합니다.

프로그래밍 언어는 도구 일뿐이기 때문에 코드를 작성하기 전에 병렬 및 다중 스레드 프로그래밍에 대한 많은 책을 읽어야합니다. 행운을 빕니다!

관련 문제