Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 程序不';不要使用所有的硬件资源_C#_Multithreading - Fatal编程技术网

C# 程序不';不要使用所有的硬件资源

C# 程序不';不要使用所有的硬件资源,c#,multithreading,C#,Multithreading,我正在开发一个程序,它从文件中获取信息,然后将它们存储在MySQL数据库中。这个MySQL数据库位于另一个专用服务器上,它比这里的服务器功能强大得多。使用1gbps连接通过LAN发送数据 它使用8个线程,因为我的服务器有8个内核,但不知为什么它运行得太慢了 CPU为:英特尔至强E3-1270 v 3@3.50Ghz RAM:16gbecc 硬盘驱动器:SATA 3 1TB 我的程序的CPU使用率只有0-5% CPU亲和力全部为8核 那么,你有什么想法吗?我该如何提高程序的速度 更新: 我更新

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

它使用8个线程,因为我的服务器有8个内核,但不知为什么它运行得太慢了

  • CPU为:英特尔至强E3-1270 v 3@3.50Ghz
  • RAM:16gbecc
  • 硬盘驱动器: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();

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

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

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

相反,更好的目标是尽可能快地做到。这是明显不同的。虽然使用更多的硬件资源会有所帮助,但这并不总是足够的

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

C#已经在TPL(您已经在使用)中具有良好的异步编程特性,所以为什么不利用它呢

这意味着.NET framework将以高效的方式自动为您管理线程

以下是我的建议:

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受限的程序中,如果使用锁,线程(和任务)也可能对您没有帮助。 虽然锁有助于保持程序的良好性能,但它们会带来巨大的性能代价

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

这意味着第一个线程正在锁定您的
\u lock
实例,然后其他线程正在等待释放该锁

在您的程序中,一次只有一个线程处于活动状态

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


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

如果没有ParseFile\GetFile方法,很难判断瓶颈在哪里。但我怀疑这是文件系统的瓶颈。如果所有资源都这么容易利用,我们中的一些人就不会有工作了D:D:D您的程序可能是I/O绑定的。一般来说,从磁盘读取文件这样的操作非常慢,即使它们不太占用CPU。我用更多信息更新了我的帖子。在
GetFiles
中,你有
lock
,它阻止所有其他线程读取不同的文件。这对多线程不太好,我添加了“获取文件”函数。我还用数据库更新了我的帖子information@Jason好的……这里的要点是,无论你做什么,你都不会有很高的CPU利用率。CPU时间对于您的程序来说不是稀缺资源,您拥有的CPU时间远远超过您的需要。如果你想让你的程序更快,你需要更有效地利用你的硬盘和网络连接。查看它们的利用率,并确保它们得到有效利用,并且只有在真正需要时才使用它们。嗯,磁盘唯一使用的是读取文件。。而且网络的速度足够快,所以不可能是网络的问题。最大IO大约为240kb/s@Jason从磁盘读取文件通常要比大多数CPU限制的操作花费几个数量级的时间。网络通信通常要比磁盘IO长几个数量级。即使你有一个快速的网络连接,它几乎肯定会成为瓶颈。对于这样一个程序,除了文件/网络IO之外,它实际上什么都做不了,因此CPU利用率不应该很高。这样做可能表明出了问题。@Jason关键是CPU利用率低不是问题。为了让程序运行得更快,您需要查看磁盘/网络利用率,如果其中一个(尤其是网络)利用率较低,请查看如何提高利用率。接下来看看减少或优化这些操作的方法,而不是CPU限制的操作。感谢您的精彩解释,我将尝试一下。我试过你的方法,但它告诉我上下文中不存在异步:也许将x数量的文件加载到列表中并从另一个线程监视它是有意义的,如果它需要更多的项目,它将加载更多
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();
}