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_Multicore - Fatal编程技术网

C# 多线程哪一种最好使用?(线程池或线程)

C# 多线程哪一种最好使用?(线程池或线程),c#,multithreading,multicore,C#,Multithreading,Multicore,希望这是一个比我以前提出的问题更好的问题。我有一个.exe,我将向它传递不同的参数(文件路径),然后它将接收并解析该参数。因此,我将有一个循环,循环列表中的文件路径,并将它们传递给这个.exe文件 为了提高效率,我希望将执行分散到多个核心上,我认为这是通过线程实现的 我的问题是,我应该使用线程池还是多个线程异步运行这个.exe 另外,取决于你们认为哪一个是最好的,如果你们能给我指一个教程,里面会有一些关于我想做什么的信息。谢谢大家! 编辑: 我需要将.exe的执行次数限制为每个核心执行一次。这是

希望这是一个比我以前提出的问题更好的问题。我有一个.exe,我将向它传递不同的参数(文件路径),然后它将接收并解析该参数。因此,我将有一个循环,循环列表中的文件路径,并将它们传递给这个.exe文件

为了提高效率,我希望将执行分散到多个核心上,我认为这是通过线程实现的

我的问题是,我应该使用线程池还是多个线程异步运行这个.exe

另外,取决于你们认为哪一个是最好的,如果你们能给我指一个教程,里面会有一些关于我想做什么的信息。谢谢大家!

编辑: 我需要将.exe的执行次数限制为每个核心执行一次。这是最有效的,因为如果我解析100000个文件,我不能启动100000个进程。因此,我使用线程将每次执行的次数限制为每个核心执行一次。如果有其他方法(线程除外)来确定处理器是否在执行中没有被占用,或者.exe是否已完成,请解释。 但如果没有其他方法,我的最后一个问题是如何使用线程调用解析方法,然后在该线程不再使用时再调用

第二次更新(非常重要):

Main thread;
   Create thread safe queue
   Populate the queue with all the file paths
   Create child threads and wait for them to finish

      Child threads:
         While queue is not empty  << this section is critical, not more then one  
            pop file from queue    << thread can check and pop at the time

            start external exe
                wait for it....
            end external exe 

         end while
      Child thread exits

   Main thread waits for all child threads to finish
Program finishes.

我仔细阅读了所有人告诉我的内容,发现了一个我认为无关紧要的关键因素,我遗漏了它。所以我使用的是GUI,我不希望它被锁定。这就是为什么我想使用线程。我现在的主要问题是,如何从线程发回信息,以便知道执行何时结束?

如果要启动.exe,那么您别无选择。您将在一个单独的进程中异步运行它。对于执行启动的程序,我建议您使用单个线程并保留已启动进程的列表。

如果您的目标是.Net 4 framework,则Parallel.For或Parallel.Foreach非常有用。如果这些不符合您的要求,我发现Task.Factory非常有用,而且使用起来也很简单。

启动的每个exe都将在其自己的进程中发生。您不需要使用一个线程池或多个线程;操作系统管理进程(因为它们是进程而不是线程,所以它们是非常独立的;完全独立的内存空间等等)。

正如我在回答上一个问题时所说的,我认为您不理解进程和线程之间的区别。过程极其“沉重”(*);每个进程可以包含许多线程。如果从父进程派生新进程,则该父进程不需要创建新线程;每个进程都有自己的线程集合

如果所有工作都在同一进程中完成,则仅在父进程中创建线程

将线程视为工作线程,将进程视为包含一个或多个工作线程的建筑

其中一个策略是“建造一座大楼,并在其中安置十名工人,每个人都做一些工作”。您将获得构建一个进程和十个线程的费用

如果你的策略是“建造一座大楼,然后让该大楼中的一名工人再建造一千栋大楼,每栋大楼都有一名工人参与竞标”,那么你就可以得到建造1001栋大楼和雇佣1001名工人的费用

你不想追求的策略是“建造一座大楼。在那座大楼里雇佣1000名工人。然后指导每个工人建造一座大楼,然后让一名工人去做真正的工作。”制作一个线程的唯一任务是创建一个进程,然后创建一个线程是没有意义的!你有1001栋大楼和2001名工人,其中一半立即闲置,但仍需支付工资

看看您的具体问题:关键问题是“瓶颈在哪里?”生成新进程或新线程只有在性能问题是性能被限制在处理器上时才有帮助。如果解析器的性能不是取决于解析文件的速度,而是取决于将文件从磁盘上取下的速度,那么并行化将使事情变得更糟。您将有大量的系统资源用于同时在同一个磁盘控制器上执行所有操作,并且磁盘控制器将随着负载的增加而变慢

更新: 我需要将.exe的执行次数限制为每个核心执行一次。这是最有效的,因为如果我解析100000个文件,我不能启动100000个进程。因此,我使用线程将每次执行的次数限制为每个核心执行一次。如果有其他方法(线程除外)来确定处理器是否在执行过程中未被占用,或者.exe是否已完成,请解释

这似乎是一种非常复杂的方式。假设您有n个处理器。据我所知,您提出的策略是启动n个线程,然后让每个线程启动一个进程,您知道,由于操作系统可能会为每个CPU调度一个线程,因此处理器也会神奇地在不同的CPU上调度每个新进程中的新线程

这似乎是一个曲折的推理链,取决于操作系统的实现细节。这是疯狂如果要设置特定进程的处理器相关性,只需不要用线程做这种疯狂的事情,希望它能成功

我要说的是,如果您希望一个可执行文件的运行实例不超过n个,每个处理器一个,那么就根本不要乱动线程。相反,只要有一个线程在一个循环中。如果运行的可执行文件少于n个副本,则生成另一个副本,并将其处理器关联设置为您最喜欢的CPU。如果有n或mor
Main thread;
   Create thread safe queue
   Populate the queue with all the file paths
   Create child threads and wait for them to finish

      Child threads:
         While queue is not empty  << this section is critical, not more then one  
            pop file from queue    << thread can check and pop at the time

            start external exe
                wait for it....
            end external exe 

         end while
      Child thread exits

   Main thread waits for all child threads to finish
Program finishes.
Parallel.ForEach(args, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (element) => Console.WriteLine(element));