C++ 如何编写代码使程序中的8个线程始终处于活动状态?

C++ 如何编写代码使程序中的8个线程始终处于活动状态?,c++,multithreading,pthreads,C++,Multithreading,Pthreads,我的代码必须独立处理几百个文件。我想让我的程序一直处理8个线程。一旦其中一个线程完成,我想启动一个处理新文件的新线程,而不阻塞所有线程的代码,直到最后 我在linux上使用pthread 我不知道如何编写这个代码。pthread\u join()是否阻止代码执行?如何知道一个线程何时完成?这段代码是如何执行的 pthread_join(thread1) pthread_join(thread2) thread1必须在执行pthread\u join(thread2)之前完成吗 所以,如果我 f

我的代码必须独立处理几百个文件。我想让我的程序一直处理8个线程。一旦其中一个线程完成,我想启动一个处理新文件的新线程,而不阻塞所有线程的代码,直到最后

我在linux上使用pthread

我不知道如何编写这个代码。
pthread\u join()
是否阻止代码执行?如何知道一个线程何时完成?这段代码是如何执行的

pthread_join(thread1)
pthread_join(thread2)
thread1必须在执行
pthread\u join(thread2)
之前完成吗

所以,如果我

for (i=0;i<7;i++)
    pthread_join(thread[i])
cout<<"Here!";

for(i=0;i创建一个新线程是有成本的,没有理由为每个文件生成一个新线程。此外,还需要做额外的工作来跟踪这些线程,以便在需要时加入它们

更好的方法是使用单个同步队列。主线程将插入作业(例如,路径),您的工作线程可以从队列中读取并处理每个文件。工作线程将阻塞,直到将作业插入队列

如果您没有访问同步队列的权限,那么通过在操作上使用互斥锁来创建一个队列应该相当容易

pthread_join确实会阻塞,直到提供的线程完成。因此,在您的示例中,必须完成所有线程才能进行打印

如果您真的想在每次线程死亡时生成一个新线程,您可以在线程执行的函数返回之前调用某个函数。此函数将生成一个新线程,该线程将处理下一个文件。处理所有文件时,线程数将自动减少

pthread\u join()
是否阻止代码执行

是的,它专门等待连接的线程完成执行,并返回其退出代码。因此,调用线程将阻塞,直到发生这种情况

您会注意到,关于这一点,您的建议非常明确:

pthread\u join()
函数应暂停调用线程的执行,直到目标线程终止


正如瓦迪姆所说,正确的方法通常是每个核心有一个长寿命的线程,并使用队列或类似的方式将工作分配给线程/核心。始终停止和启动线程是低效的

换句话说,线程不是任务。线程一个接一个地执行任务


请注意,您的文件系统是否真的能让8个并发线程保持忙碌将取决于您正在做什么:文件访问可能无论如何都会通过驱动程序序列化,如果您最终受到I/O而不是CPU的限制,许多线程可能不是最有效的方法。

请原谅我的无知,但我认为拥有更多线程没有任何好处一个用于读取文件的线程

设备I/O瓶颈
除非计算机的每个硬盘都有一个单独的I/O通道,并且每个文件都在一个单独的磁盘上,否则性能瓶颈之一就是I/O通道。大多数计算机一次只能读取一个通道,或者可能会将多个通道的消息多路传输到硬盘

驱动寻道位置
在一个文件是一组连续扇区的理想情况下,您将有两个查找操作:目录查找和文件打开。驱动器将在不重新定位磁头的情况下传送所有数据

当您在单个硬盘驱动器上同时读取多个文件时,硬盘驱动器必须查找一个文件、读取一些数据、查找第二个文件、读取一些数据等,直到循环到第一个文件。对于读取的每个数据块,每个文件至少有一个查找操作。因此,累积了大量的查找时间到硬盘中的不同位置

多核一个I/O通道
在内部,数据必须从硬盘驱动器进入电脑内存。然后,相应的核心必须使用单个数据总线或单个内存区域来获取数据。想象一条有交通信号灯的单行道。每个核心将被阻塞(等待),直到数据总线(道路)可用。因此,等待时间更长

线程切换开销
线程有一个相关的成本:创建和切换。即使每个处理器有一个线程,操作系统也必须协调和管理线程。本质上,每个线程都会增加一个簿记成本,从程序的性能和内存空间中减去

一个I/O线程,多个处理线程。 使用文件实现高性能的目标是保持硬盘旋转并减少寻道操作的数量。在线程上可以轻松实现这一点

为每个处理线程分配一个缓冲区将有助于提高性能。文件读取线程将为一个处理线程填充一个缓冲区,然后转移到下一个缓冲区。具有多个处理器或内核的系统优化了数据总线共享;因此每个内核占用的阻塞时间最少

核心缓存
处理线程应将尽可能多的数据从I/O缓冲区提取到处理器的数据缓存中。这允许一个内核从其缓存中处理数据,而另一个内核从I/O缓冲区加载其缓存

物理优化
一些大学实验表明,通过对系统进行物理更改,可以大幅提高性能。例如,每个数据位使用一个硬盘驱动器。其他系统使用多个硬盘驱动器,并将文件分发到多个硬盘驱动器,以缓解对单个驱动器的需求。有些系统实际上有多个I/O通道to内存。直接内存访问(DMA)控制器可以在处理器执行其他操作时将数据从I/o端口提取到内存中

S