【问题标题】:How to multi-thread input/output process and cpu process如何多线程输入/输出进程和cpu进程
【发布时间】:2015-03-21 17:43:52
【问题描述】:

我正在编写一个加密程序来加密文件(大小)来做到这一点,我目前的方法是从文件中读取 1024 个字节,加密这些字节,并将它们写入临时文件,然后重复直到完成.此过程完成后,将删除原始文件并将临时文件重命名为原始文件的名称。

这是一段处理 n 字节(n 为 1024)的示例代码:

        private void processChunk(BinaryReader Input, BinaryWriter Output, int n)
    {
        // Read n bytes from the input fileStream
        Byte[] Data = Input.ReadBytes(n);
        // Read n bytes from the streamCipher
        Byte[] cipherData = StreamCipher.OutputBytes(n);
        for (int x = 0; x < n; x++)
            // XOR a byte of the input stream with a corresponding byte of the streamCipher
            Data[x] ^= cipherData[x];
        // Write n bytes to the output fileStream
        Output.Write(Data);
    }

所以我很确定我不能对加密算法进行多线程处理,因为字节是作为密钥流生成的,并且取决于之前生成的字节,但是从文件和 cpu 操作中读取和写入可以吗?

最好的策略是什么?

【问题讨论】:

  • 为什么不使用现有的加密算法?
  • 因为我非常喜欢信息安全的职业,我想了解加密的本质及其应用。这段代码是我的 a-level 课程的一部分 :)

标签: c# wpf multithreading encryption


【解决方案1】:

自发地,我建议并行运行三个线程:

  1. 将数据块读入内存的读取器线程。
  2. 一个加密线程完成所有工作。
  3. 将加密数据写入磁盘的写入器线程。

三个线程通过两个队列进行通信,如 .Net 4 提供的 BlockingCollection。参见Fast and Best Producer/consumer queue technique BlockingCollection vs concurrent Queue

所以线程 1 填充队列 1,线程 2 读取队列 1 并填充队列 2,线程 3 读取队列 3。如果任何线程比其他线程快,BlockingCollection 将阻塞读取或写入线程,直到线程打开对方已经追了上来。例如,如果将 BlockingCollection 设置为最大大小 10,则读取线程将在加密线程之前读取 10 个数据块后阻塞。

还有一个观察:Input.ReadBytes 将为每次读取在堆上分配一个新的字节数组。这个数组将在当前块被处理后被丢弃,所以如果你有大文件和快速加密算法,内存分配和垃圾收集实际上可能会显着影响性能(.Net 在分配时将内存缓冲区归零)。相反,您可以使用由读取和加密线程保留和返回的缓冲区池,并使用 Stream.Read 方法接受现有缓冲区进行写入。

【讨论】:

  • 这是个好建议!我会尽快尝试实现你的想法,关于你的观察,你是说填充缓冲区并覆盖它的数据而不是让它被垃圾收集更好吗?
  • 是的,完全正确。由于无论如何您都在用新数据填充缓冲区,覆盖以前的数据,因此让 .Net GC 在每个周期收集缓冲区、重新分配和清除它们是没有意义的。哦,如果您喜欢我的回复,我会很感激您将其标记为您的问题的答案:-)
【解决方案2】:

你可以这样做:

  1. 读取所有数据并将其存储在列表中,其中每个条目是根据n的字节数组
  2. 运行加密并将所有加密字节保存在内存中。

  3. 一次写入所有输出字节。

这样您只能访问文件两次。

【讨论】:

  • 不可能对于较大的文件,将 500mb 或更大的文件完全加载到系统内存中会产生错误,这就是我以块为单位管理数据的原因。不过感谢您的建议:)
  • 你仍然可以这样做,只需定义一个最大尺寸。让我们说 1MB 并根据需要多次执行此操作
  • 所以实际上你说的是分块进行加密?我试图通过一次执行多个任务来加快进程,cpu 任务可以在读取和写入磁盘的同时执行,所以当我可以加密字节时为什么要等待读取数据同一时间?
猜你喜欢
  • 1970-01-01
  • 2020-07-30
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多