【问题标题】:Is it possible to split looping through a file into many threads?是否可以将循环通过文件拆分为多个线程?
【发布时间】:2011-08-24 20:34:27
【问题描述】:

我正在尝试实施一个解决方案,我遇到了另一个问题(http://stackoverflow.com/questions/7166223/create-password-breaker-for-iphone-backup-files)。解决方案非常简单。问题是我正在使用一本包含大约 250 000 个单词的字典。对于每个单词,我以特定模式添加字母和数字,以获得我通常使用的不同组合。我去掉了我很少使用的组合,但每个单词仍然有大约 24 个组合,因此最终的单词列表将是 600 万左右。

因此,创建列表的过程非常缓慢。我在想也许多线程可以解决我的问题。我的理论是我可以说 4 个线程(我是线程新手,不知道这是否可能)。在线程 1 中,我使用字典的前四分之一,在线程 2 中,我使用第二个四分之一,依此类推。每个线程都会循环遍历字典中的单词,并添加不同的组合。当每个线程完成时,它会将结果写入线程特定的文本文件。当所有线程都完成工作后,我会将不同的文件连接成一个大文本文件(其中包含所有 600 万字)。从而将处理时间缩短为 4。至少这是我所希望的。 :=)

我正在使用 C#。这可能吗?简而言之:是否可以使用 C# 中的不同线程循环遍历文本文件的不同部分?有什么特别值得我考虑的吗?

我会尝试使用它,但我们非常感谢您提出的任何建议。

【问题讨论】:

    标签: multithreading loops text-files


    【解决方案1】:

    这很有可能,假设您有一种快速划分列表的方法(我认为打破中间词会很糟糕)。

    但是,请记住,除非您有多余的处理能力可以使用,否则线程什么也做不了。如果您使用的是单 CPU/单核 PC,那么您将尽可能快地运行。但是,如果您有多个 CPU(或至少多个内核),那么这是有机会的。

    实施相当简单。如果您目前正在这样做:

    ProcessText(fullTextBlock);
    

    那就是:

    ThreadPool.QueueUserWorkItem(ProcessText, textBlock1);
    ThreadPool.QueueUserWorkItem(ProcessText, textBlock2);
    ThreadPool.QueueUserWorkItem(ProcessText, textBlock3);
    ThreadPool.QueueUserWorkItem(ProcessText, textBlock4);
    

    【讨论】:

    • 非常感谢您快速回答詹姆斯! :=) 恐怕我在单核 PC 上。那么使用单核pc时不能使用多线程?我的想法是说 4 种不同的方法:getPassword1()、getPassword2() 等。不是非常面向对象,因为它们会做同样的事情。但这只是一次(希望;=)),所以我认为这可能是一个简单的解决方案。然后我会让每个线程调用它自己的单独方法。但如果我理解你,那不可能?
    • 嘿詹姆斯!我创建了一个简单的控制台应用程序,我可以在其中选择要使用的线程数。我尝试使用 100 个线程,效果很好。我写了时间来处理一定数量的单词,并且在使用多个线程时时间大大减少了。为避免冲突,我将原始密码文件分成相等的部分。每个线程根据其部分创建密码,然后将结果写入自己的文件。是否只有在与相同的方法和变量交互时,线程才会构成威胁?
    • 詹姆斯,我在 stackoverflow 上没有足够的“信誉”来支持你的答案,但这是我的一个大拇指! :=)
    【解决方案2】:

    由于这是我第一次尝试使用线程,我想我可能会分享我实现的解决方案。如果有人对如何改进这一点有任何建议,那就太好了。我对线程的理解是,当线程与相同的方法或变量交互时,使用线程可能是一个大问题。但我认为我确实完全分开了线程。他们正在使用我创建的类的不同实例。因此,如果有人对这种使用线程的方式有一些好的建议,我很高兴。 :=) 这是我用来渲染线程的代码:

     for (int i = 0; i < threads; i++)
                {
                    string errorFileName = "errorFile" + (i + 1) + ".dic";
                    string saveFileName = "english" + (i + 1) + ".dic";
                    string logfileName = "error.log";
                    string[] currentContent;
                    if (i != threads - 1)
                    {
                        currentContent = contentArrayOriginal.Skip(skipStrings).Take(takeStrings).ToArray();
                    }
                    else
                    {
                        int skip = skipStrings;
                        int take = numberOfWords - skip;
                        currentContent = contentArrayOriginal.Skip(skip).Take(take).ToArray();
                    }
                    PasswordRendering passRender = new PasswordRendering(rootFilePath, errorFilePath, dictionariesFilePath, currentContent, versionsMain, errorFileName, saveFileName, logfileName, (i + 1));
                    Thread thread = new Thread(new ThreadStart(passRender.SetPasswords));
                    thread.Start();
                    skipStrings += takeStrings;
                }
    

    这里是保存渲染密码的代码(在 PasswordRendering 类中):

    File.WriteAllText(dictionariesFilePath + saveFileName, newContent);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-05
      • 2021-02-13
      • 1970-01-01
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      相关资源
      最近更新 更多