多线程程序逻辑

本文关键字:程序 多线程 | 更新日期: 2023-09-27 18:05:22

我的教授给了我这个半伪代码。他说我应该在这段代码的逻辑中找到一个错误。此刻我找不到任何东西,可能是什么问题。你能给我提示一下哪里出了问题吗?我不是在要求答案,因为我想自己找到答案,但如果能给我一些提示,告诉我应该朝哪个方向看,那就太棒了。

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

多线程程序逻辑

toContinue = false;

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

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

异常处理

可能是异常处理的问题。经常检查程序中可能出现意外结果的地方。
如果这个变量的值不是我们所期望的,这段代码将如何表现?
如果除以0会怎样?
诸如此类。

查看变量初始化的位置,并问自己是否有可能没有按预期的方式初始化?

异常处理(c#编程指南)

方法调用

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

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

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

质疑呼叫:例如

 Update(progressValue);

这到底有什么用?

类库

线程

像这样调用三个线程是如何工作的呢?
它们需要协调吗?
线程是否应该休眠,以允许其他操作完成?

也适用于访问来自不同线程的变量。
跟踪这个变量的值会不会很麻烦?
它们被覆盖了吗?


线程类如何:创建和终止线程(c#编程指南)

<<p> 命名约定/strong>

在c#中还有一些命名约定的问题。在c#中,使用泛型var使用隐式类型比使用显式类型声明更可取。

c#编程规范(c#编程指南)

我并不是说所有这些观点都有问题,但是如果你调查了所有这些观点和其他答案中的观点,你会发现所有的错误,你会更好地理解你正在阅读的代码

项目如下:

  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

有几个;我只列举两个明显的,我认为这不是一个如何编写精确和正确的多线程代码的练习。

你应该问自己以下问题:

  1. progressValue应该测量从0到100的工作的进度(进度值等于150似乎有点偏离,不是吗?)它真的在这样做吗?
  2. 你不应该停止更新progressValue (Update(progressValue)),直到所有的工作完成。你真的要这么做吗?

我不太了解多线程,但我会尽量给一些提示。首先看看全局变量,当您在不同的线程中访问相同的变量时会发生什么?

除了其他答案的提示,我找不到任何其他"错误"。