多线程程序逻辑

时间:2016-09-03 08:27:21

标签: c# multithreading thread-safety

我的教授给了我这个半伪代码。他说我应该在这段代码的逻辑中找到一个错误。目前我找不到任何东西,可能是错的。你能不能给我一些关于可能出错的提示?我不是要求答案,因为我想自己找到答案,但是我应该看到哪些方向的提示会很棒。

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);
    }
  }
}

5 个答案:

答案 0 :(得分:3)

toContinue = false;

这是在第一个完成线程结束时设置的 - 这将导致ProgressThread在第一个线程完成时立即停止,而不是在两个线程完成时停止。应该有两个单独的线程完成标志,两者都应该被检查。

答案 1 :(得分:1)

要添加已经提供的好答案 ,我有点彻底,但想法是学习。

异常处理

可能是异常处理的问题。请务必检查程序中是否有可能出现意外结果的地方  如果此变量的值不是我们所期望的,那么此代码将如何表现? 如果我们除以零会发生什么? 这样的事情。

看看变量初始化的位置,并问自己是否有可能无法以预期的方式进行初始化?

Exception Handling (C# Programming Guide)

方法调用

还要检查代码中使用的所有库。例如加密。
 问问自己,这些陈述会给我一个预期的结果吗? e.g。

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

这会返回一个字符串数组吗?  这是我应该如何初始化字符串数组?

询问电话: e.g。

 Update(progressValue);

这到底是做什么的?

Class Library

线程

如何调用这样的三个线程 他们需要协调吗?  线程是否应该睡眠,以便完成其他操作?

同样从不同的线程访问变量 试图追踪该变量的价值会不会有一团糟?  他们被覆盖了吗?

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

命名约定

在较小的说明中,C#中的命名约定存在问题。使用泛型var的隐式类型优于C#中的显式类型声明。

C# Coding Conventions (C# Programming Guide)

我并不是说所有这些问题都存在问题,但如果您调查所有这些问题以及其他答案中提出的要点,您会发现所有错误,并且您将更好地了解您正在阅读的代码。

答案 2 :(得分: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

答案 3 :(得分:0)

有一些;我只列举了两个显而易见的问题,我想这不是一个如何编写精确和正确的多线程代码的练习。

您应该问自己以下问题:

  1. progressValue应衡量工作从0到100的进度(等于150的进度值似乎有点偏,不是吗?)。这真的是这样吗?
  2. 在所有工作完成之前,您不应该停止更新progressValueUpdate(progressValue))。你真的这样做吗?

答案 4 :(得分:0)

我不太了解多线程,但是我试图提供一些提示。 首先看一下全局变量,当你在不同的线程中访问同一个变量时会发生什么?

除了对另一个答案的提示外,我找不到其他任何东西"错误"。