2017-11-16 18 views
-2

5 개의 스레드를 동시에 실행하는 프로그램을 만들었습니다. 이 5 개의 스레드는 각각 약 3 시간 동안 지속될 수있는 여러 시간 소모적 인 작업을 각각 실행합니다.i5 CPU에서 4 개 이상의 스레드를 실행할 수 없습니까?

2 시간 전에는 UI가 정상적으로 작동하는 것 같습니다. 그러나 약 2 시간이 지나면 UI가 응답하지 않고 지연된다는 것을 발견했습니다. 또한 5 번째 스레드의 결과가 잘못되거나 가짜 값을 갖습니다. 코딩 최적화에 최선을 다했으나 여전히 발생합니다.

회사 컴퓨터에는 i5-6500 CPU와 8GB RAM이 있습니다. 이 CPU는 한 번에 4 개의 스레드 만 실행할 수 있다고 온라인에서 확인했습니다. 5 개 이상의 스레드를 실행하려면 하이퍼 스레딩 기능이있는 i7-7700이 필요하며 한 번에 8 개씩 실행할 수 있습니다.

이 하드웨어 제한 사항에 관해서는 맞습니까? 아니면이 문제를 극복하기 위해 C#으로 코딩 할 수있는 무언가가 있습니까? 참고로, 저는 멀티 쓰레딩을 처리하기 위해 BackgroundWorker를 사용하고 있습니다.

내 상사에게 새로운 CPU 및 마더 보드에 투자해야한다는 것을 제안하기 전에 하드웨어 문제인지 확인해야합니다.

모든 조언을 크게 듣습니다. :)

private void Form1_Load(object sender, EventArgs e) 
{ 
    using (StreamReader sr = new StreamReader(string.Concat(Directory.GetCurrentDirectory(), "\\limit.txt"), true)) 
     { 
      String input; //read value limits from textfile and storing it in array 
      int i = 1; 
      while ((input = sr.ReadLine()) != null) 
      { 
       limit_memory[i]= input; 
       i++; 
      } 
     } 
    } 

} 
private void button1_Click(object sender, EventArgs e) 
{ 
    //shows some textboxes that user has to fill and press enter to continue 
} 
private void button2_Click(object sender, EventArgs e) 
{ 
    //shows some textboxes that user has to fill and press enter to continue 
} 
private void button3_Click(object sender, EventArgs e) 
{ 
    //shows some textboxes that user has to fill and press enter to continue 
} 
private void button4_Click(object sender, EventArgs e) 
{ 
    //shows some textboxes that user has to fill and press enter to continue 
} 
private void button5_Click(object sender, EventArgs e) 
{ 
    //shows some textboxes that user has to fill and press enter to continue 
} 

private void textBox1_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    if (e.KeyChar == '\r') 
     { 
     if (backgroundWorker1.IsBusy != true) 
      { 
       object[] button1_var = { sentry1, terminal1, txtBox1_serial}; 
       backgroundWorker1.RunWorkerAsync(button1_var); //pass some arguments with an object 
      } 
     } 
} 

private void textBox2_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    if (e.KeyChar == '\r') 
     { 
     if (backgroundWorker2.IsBusy != true) 
      { 
       object[] button2_var = { sentry2, terminal2, txtBox2_serial}; 
       backgroundWorker2.RunWorkerAsync(button2_var); //pass some arguments with an object 
      } 
     } 
} 
private void textBox3_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    if (e.KeyChar == '\r') 
     { 
     if (backgroundWorker3.IsBusy != true) 
      { 
       object[] button3_var = { sentry3, terminal3, txtBox3_serial}; 
       backgroundWorker3.RunWorkerAsync(button3_var); //pass some arguments with an object 
      } 
     } 
} 
private void textBox4_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    if (e.KeyChar == '\r') 
     { 
     if (backgroundWorker4.IsBusy != true) 
      { 
       object[] button4_var = { sentry4, terminal4, txtBox4_serial}; 
       backgroundWorker4.RunWorkerAsync(button4_var); //pass some arguments with an object 
      } 
     } 
} 
private void textBox5_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    if (e.KeyChar == '\r') 
     { 
     if (backgroundWorker5.IsBusy != true) 
      { 
       object[] button5_var = { sentry5, terminal5, txtBox5_serial}; 
       backgroundWorker5.RunWorkerAsync(button5_var); //pass some arguments with an object 
      } 
     } 
} 
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     //uses the arguments passed and perform long operations 
     //prints results to textFile1 
    } 
    catch 
    { 
     throw new BackgroundWorkerException(sernum, ex);//pass the unit's serial number to the error handler 
    } 
} 
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     //uses the arguments passed and perform long operations 
     //prints results to textFile2 
    } 
    catch 
    { 
     throw new BackgroundWorkerException(sernum, ex);//pass the unit's serial number to the error handler 
    } 
} 
private void backgroundWorker3_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     //uses the arguments passed and perform long operations 
     //prints results to textFile3 
    } 
    catch 
    { 
     throw new BackgroundWorkerException(sernum, ex);//pass the unit's serial number to the error handler 
    } 
} 
private void backgroundWorker4_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     //uses the arguments passed and perform long operations 
     //prints results to textFile4 
    } 
    catch 
    { 
     throw new BackgroundWorkerException(sernum, ex);//pass the unit's serial number to the error handler 
    } 
} 
private void backgroundWorker5_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     //uses the arguments passed and perform long operations 
     //prints results to textFile5 
    } 
    catch 
    { 
     throw new BackgroundWorkerException(sernum, ex);//pass the unit's serial number to the error handler 
    } 
} 
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    //updates the UI on what operations are being run 
} 
private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    //updates the UI on what operations are being run 
} 
private void backgroundWorker3_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    //updates the UI on what operations are being run 
} 
private void backgroundWorker4_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    //updates the UI on what operations are being run 
} 
private void backgroundWorker5_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    //updates the UI on what operations are being run 
} 
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Cancelled == true) //if user cancels thread 
    { 
    //disconnect unit from PC, clears UI 
    } 
    else if(e.Error != null) //if error occurs in thread 
    { 
    string sernum = ((BackgroundWorkerException)e.Error).Sernum; 
    //logs the serial number and error into a log text file 
    } 
    else //the program ends normally 
    { 
     //disconnect unit from PC, clears UI 
    } 
} 
private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Cancelled == true) //if user cancels thread 
    { 
    //disconnect unit from PC, clears UI 
    } 
    else if(e.Error != null) //if error occurs in thread 
    { 
    string sernum = ((BackgroundWorkerException)e.Error).Sernum; 
    //logs the serial number and error into a log text file 
    } 
    else //the program ends normally 
    { 
     //disconnect unit from PC, clears UI 
    } 
} 
private void backgroundWorker3_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Cancelled == true) //if user cancels thread 
    { 
    //disconnect unit from PC, clears UI 
    } 
    else if(e.Error != null) //if error occurs in thread 
    { 
    string sernum = ((BackgroundWorkerException)e.Error).Sernum; 
    //logs the serial number and error into a log text file 
    } 
    else //the program ends normally 
    { 
     //disconnect unit from PC, clears UI 
    } 
} 
private void backgroundWorker4_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Cancelled == true) //if user cancels thread 
    { 
    //disconnect unit from PC, clears UI 
    } 
    else if(e.Error != null) //if error occurs in thread 
    { 
    string sernum = ((BackgroundWorkerException)e.Error).Sernum; 
    //logs the serial number and error into a log text file 
    } 
    else //the program ends normally 
    { 
     //disconnect unit from PC, clears UI 
    } 
} 
private void backgroundWorker5_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Cancelled == true) //if user cancels thread 
    { 
    //disconnect unit from PC, clears UI 
    } 
    else if(e.Error != null) //if error occurs in thread 
    { 
    string sernum = ((BackgroundWorkerException)e.Error).Sernum; 
    //logs the serial number and error into a log text file 
    } 
    else //the program ends normally 
    { 
     //disconnect unit from PC, clears UI 
    } 
} 
public class BackgroundWorkerException : Exception //to pass serial number to error handler 
    { 
     public string Sernum { get; set; } 

     public BackgroundWorkerException(string sernum, Exception ex) 

     { 
      Sernum = sernum; 
     } 
    } 

편집 : 내 Backgroundworker의 구조를 표시하는 코드가 추가되었습니다.

+0

설명은 확장 토론이 아닙니다. 이 대화는 [채팅으로 이동되었습니다] (http://chat.stackoverflow.com/rooms/159405/discussion-on-question-by-user107257-i-cannot-run-more-than-4-threads-on- an-i5-c). – Andy

답변

2

i5-6500에는 4 개의 hardwarethreads가 있습니다. 즉, 코어 사용량이 splittet을 가지며 4 개의 스레드로 최적화되었습니다. 당신이 원하는대로 당신은 모든 CPU에 많은 자국을 시작할 수 있지만 그 때처럼 실행됩니다 : 싱글 코어 예 : 다시, B를 중지

시작 A, A, 시작 B를 중지하고 시작하는 중지 , 별 B 다시.

+0

멀티 스레딩을 처리하기 위해 BackgroundWorker를 사용하고 있습니다. 이러한 스레드의 순서가 올바르게 작동하는 방법을 최적화한다고 가정합니다. 하지만 내 UI는 여전히 반응이 없습니다. – user107257

+0

이제는 정상적으로 실행될 수 있습니다. 만약 당신이 더 많은 코드와 핸들러를 게시하고 싶다면/... – LenglBoy

+0

그 방법은 당신이 그 BGW를 어떻게 사용 하느냐에 달려 있습니다. 여전히 응답 성을 엉망으로 만들 수 있습니다. – Fildor