2016-09-03 2 views
3

Мой профессор дал мне этот полу-псевдокод. Он сказал, что я должен найти ошибку где-то в логике этого кода. На данный момент я ничего не могу найти, что может быть неправильным. Не могли бы вы дать мне несколько намеков о том, что может быть неправильным? Я не прошу ответа, потому что я хотел бы найти его сам, но некоторые намеки на то, в каком направлении я должен выглядеть, были бы замечательными.Многопоточная программная логика

class Program 
{ 
    int progressValue = 0; 
    int totalFiles = 0; 
    int i = 0; 
    bool toContinue = true; 

void MasterThread() 
{ 
    Thread thread1 = new Thread(Worker1); 
    Thread thread2 = new Thread(Worker2); 
    Thread progressThread = new Thread(ProgressThread); 

    thread1.Start(); 
    thread2.Start(); 
    progressThread.Start(); 
} 

void Worker1() 
{ 
    string[] files = Directory.GetFiles(@"C:\test1"); 
    totalFiles += files.Length; 
    foreach (string file in files) 
    { 
     Encryption.Encrypt(file); 
     i++; 
     progressValue = 100 * i/totalFiles; 
    } 
    toContinue = false; 
} 

void Worker2() 
{ 
    string[] files = Directory.GetFiles(@"C:\test2"); 
    totalFiles += files.Length; 
    foreach (string file in files) 
    { 
     Encryption.Encrypt(file); 
     i++; 
     progressValue = 100 * i/totalFiles; 
    } 
    toContinue = false; 
} 

void ProgressThread() 
{ 
    while (toContinue == true) 
    { 
     Update(progressValue); 
     Thread.Sleep(500); 
    } 
    } 
} 
+0

Параллельный доступ к переменной? –

+0

Я задал этот вопрос, и все ответы были выше, я думаю, что это отличный стиль вопроса. Это на самом деле весело. –

+1

Спасибо всем за ответы и ваше время, что вы потратили ответы и пытались мне помочь! Я обязательно рассмотрю все, что вы указали! Благодаря! – Martin

ответ

1

Чтобы добавить хорошие ответы, которые уже предусмотрены, я, будучи немного тщательно, но идея состоит в том, чтобы учиться.

Обработка исключений

Может быть проблемы с обработкой исключений. Всегда проверяйте свою программу на наличие мест, где может быть неожиданный результат.
Как будет выглядеть этот код, если значение этой переменной не такое, чего мы ожидаем?
Что произойдет, если мы разделим на ноль?
Такие вещи.

Посмотрите, где инициализируются переменные, и спросите себя, есть ли вероятность, что это может не инициализировать так, как ожидается?

Exception Handling (C# Programming Guide)

Метод вызовов

Также проверьте все библиотеки, которые используются в коде. например Шифрование.
Спросите себя, будут ли эти заявления дать мне ожидаемый результат? , например.

string[] files = Directory.GetFiles(@"C:\test1"); 

Будет ли это возвращать массив строк?
Это как я должен инициализировать массив строк?

Вопрос о вызовах: , например.

Update(progressValue); 

Что это на самом деле?

Class Library

Резьбонарезной

Как это будет работать три вызова темы, как это.
Нужно ли им координировать?
Должны ли потоки спать, чтобы разрешить другие действия?

Также как для доступа к переменным из разных потоков.
Будет ли беспорядок попыткой отслеживать значение этой переменной?
Они переписываются?

Thread Class
How to: Create and Terminate Threads (C# Programming Guide)

соглашение об именах

В меньшее примечании есть проблемы с именования в C#. Использование неявной типизации с использованием общего var предпочтительнее явных деклараций типов в C#.

C# Coding Conventions (C# Programming Guide)

Я не говорю, что есть проблемы со всеми этими точками, но если вы исследуете все эти и замечание, сделанное в других ответах, вы найдете все ошибки и вы получите лучшее понимание кода, который вы читаете.

0

Есть несколько; Я просто перечислил два очевидных вопроса, полагаю, что это не упражнение, как кодировать точный и правильный многопоточный код.

Вы должны задать себе следующие вопросы: (? Значение прогресса, равное 150, кажется поодаль, не правда ли)

  1. progressValue должен измерять прогресс от нуля до ста из общей работы , Неужели это так?
  2. Вы не должны останавливать обновление progressValue (Update(progressValue)), пока вся работа не будет выполнена. Вы действительно это делаете?
+0

Спасибо, что выделили эти два, я посмотрю на них. Фактически тема называется многопоточным программированием, поэтому это может быть некоторые ошибки в логике многопоточной части. Вы видите? – Martin

+1

@ Мартин Я только что указал на вас два. – InBetween

0

Я не слишком много знаю о многопоточности, но стараюсь дать купе подсказок. Сначала посмотрите на глобальные переменные, что происходит при доступе к одной и той же переменной в разных потоках?

Помимо намеков на другой ответ, я не могу найти ничего лишнего "неправильно".

3
toContinue = false; 

Это устанавливается в конце первого заполняющего нити - это заставит ProgressThread прекратить, как только первая нить завершает, не тогда, когда оба потока завершения. Должны быть два отдельных флажка завершения потока, и оба должны быть проверены.

1

Вот детали:

  1. Там нет ничего, держась за «MasterThread» - так что трудно сказать, будет ли программа мгновенно закончится или нет.
  2. Доступ к totalFiles из двух потоков, и если оба делают это одновременно, то возможно, что тот или другой может выиграть (или оба могут частично обновить значение), поэтому не сообщается, есть ли у вас действительное значение или нет. Вместо этого следует использовать Interlocked.Add(ref totalFiles, files.Length);.
  3. Оба рабочих потока также обновляют i, которые также могут стать поврежденными. Вместо этого следует использовать Interlocked.Increment(ref i);.
  4. Нет информации, если Encryption.Encrypt является потокобезопасным. Возможно, следует использовать lock.
  5. Петля в ProgressThread является плохим - Thread.Sleep следует всегда избегать - лучше иметь явный вызов обновления (или другой механизм) для обновления прогресса.
  6. Нет информации, если Update(progressValue); является потокобезопасным. Возможно, следует использовать lock.
Смежные вопросы