程序不使用所有硬件资源

时间:2014-01-16 17:05:01

标签: c# multithreading

我正在开发一个程序,它从文件中获取信息,然后将它们存储在MySQL数据库中。这个MySQL数据库位于另一个专用服务器中,这个服务器比这个服务器强大得多。使用1gbps连接通过LAN发送数据。

它使用8个线程,因为我的服务器有8个核心,但不知怎的,它的运行速度很慢。

  • CPU为:Intel Xeon E3-1270 v 3 @ 3.50Ghz
  • RAM:16 GB ECC
  • HDD:SATA 3 1TB

我的程序的CPU使用率仅为0-5% CPU亲和力全部是8个核心

那么,你有什么想法是错的,或者我怎样才能提高程序的速度?

更新

我更新了我的代码,它看起来更快:

Parallel.For(0, this.data_files.Count, new ParallelOptions { MaxDegreeOfParallelism = this.MaxThreads }, i =>
{
        this.ThreadCount++;
        this.ParseFile(this.GetSource());                            
});

这是一个部署线程的代码片段:

while (true)
{
    if (this.ThreadCount < this.MaxThreads)
    {
        Task.Factory.StartNew(() =>
            this.ParseFile(this.GetFile())
        );

        this.ThreadCount++;
    }
    else
    {
        Thread.Sleep(1);
    }

    this.UpdateConsole();

}

GetFile功能:

private string GetFile()
{
    string file = "";
    string source = "";

        while (true)
        {
            if (this.data_files.Count() != 0)
            {
                file = this.data_files[0];
                this.data_files.RemoveAt(0);

                if (File.Exists(file) == true)
                {
                    source = File.ReadAllText(file);
                    File.Delete(file);
                    break;
                }
            }

    }

    return source;
}

2 个答案:

答案 0 :(得分:4)

  

我正在开发一个程序,它从文件中获取信息,然后将它们存储在MySQL数据库中。

显然你的程序不受CPU限制,它是IO绑定的。瓶颈将取决于您的硬盘和网络连接。甚至单个线程也可以确保正确使用这些资源(在设计良好的应用程序中)。添加额外的线程通常无济于事,它只会创建一堆线程,花费时间等待各种IO操作。

答案 1 :(得分:0)

使用所有硬件资源不是程序的正确目标。

相反,更好的目标是尽可能快地 。这是显着不同的。虽然使用更多的硬件资源可以提供帮助,但这并不总是足够的。

有时,为问题添加更多资源不会帮助。在那些情况下,不要。添加线程会使您的程序更复杂,但不一定更快,如您所见。

C#已经具有良好的TPL(你已经在使用)的异步编程功能,那么为什么不利用它?

这意味着.NET框架将以有效的方式自动为您管理线程。

这是我的建议:

foreach (var file in GetFilesToRead()) {
   var task = PerformOperation(file);
   // Keep a list of tasks, if you wish.
}

...

Task PerformOperation (string filename) {
    var file = await ReadFile(file);
    await ParseFile(file);
    DoSomething();
}

请注意,即使在CPU绑定的程序中,如果您使用锁,线程(和任务)也可能无法帮助您。 虽然锁有助于保持程序的良好运行,但它们的性能成本却很高。

在锁定中,一次只能执行一个线程

这意味着第一个线程正在锁定_lock实例,然后其他线程正在等待释放该锁。

在您的计划中,一次只有一个线程

要解决此问题,请勿使用锁定。相反,编写完全不需要锁的程序。复制变量而不是共享它们。使用不可变集合而不是可变集合等等。

我上面的程序使用了完全零锁,因此可以更好地利用你的线程。