我正在尝试理解std::thread中的一些基本概念,但我仍然对这些概念缺乏信心。根本的问题是:
当我超过std::thread::hardware_concurrency()__的值时,会发生什么,就像下面所做的那样?
我知道这个方法只是一个提示,但在这种情况下,8应该是准确的。我没有看到任何警告或错误,那么实际发生了什么呢?
我怀疑这与我对join()和detach()缺乏理解有关,这就引出了我的第二个问题。
我知道,如果我在没有join()或detach()的情况下旋转线程,就会得到运行时错误。正如我从阅读和观察中了解到的那样,join()导致线程阻塞,直到它完成执行,而detach()则基本相反,允许线程在完成之前疯狂运行,如果线程不自行终止,则可能会打开一罐蠕虫。
根据我的观察,join()和detach()的使用似乎是相互排斥的。这样做不对吗?为什么我需要在同一个线程上使用join()和detach()?
就我的第一个问题而言,我甚至无法开始猜测。我预期会出现某种类型的运行时错误,或者更明显的强制阻塞。
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <thread>
#include <vector>
std::vector<unsigned> getNumbers(unsigned n)
{
std::vector<unsigned> out;
while(n > 0)
{
out.push_back(rand());
n--;
}
return out;
}
int main() {
srand(time(nullptr));
std::vector<std::thread> threads;
unsigned maxThreads = std::thread::hardware_concurrency();
std::cout << "Max threads: " << maxThreads << std::endl;
unsigned tooManyThreads = maxThreads + 5;
for(auto i = 0; i < tooManyThreads; i++)
{
threads.push_back(std::thread(getNumbers,(rand() % 10000 + 1)));
std::cout << "Starting thread " << i << " ("
<< threads.back().get_id() << ")" << std::endl;
threads.back().detach();
}
for(auto i = 0; i < tooManyThreads; i++)
{
if(threads.at(i).joinable())
{
threads.at(i).join();
std::cout << "Joining " << i << std::endl;
}
}
return 0;
} 发布于 2019-05-01 01:41:01
发布于 2019-05-01 01:41:32
在任何给定的时间,您的计算机上都有数千个线程在运行。大多数程序或进程来自其他程序或进程,其中有数百或数千个程序或进程在后台运行。(如果在windows中打开TaskManager,或者在Linux命令提示符中键入htop,就可以看到它们)。
那么std::thread::hardware_concurrency是什么呢?它是可以同时执行的线程数。如果您有8个逻辑核心,则只能同时执行8个线程。所有其他线程都是“暂停”的,至少直到轮到它们运行为止。
这听起来像是一个矛盾:没有数千个内核,怎么可能有成千上万的线程呢?答案是操作系统会安排线程。每个活动线程都有一个回合来运行,并且运行速度足够快,以至于人们不会注意到延迟,但这些线程实际上并不是同时执行的。
基本上,std::thread::hardware_concurrency告诉您使用线程的最大可能速度。如果您有8个内核,那么使用线程并行化的最大速度是8倍。可以启动更多的线程,很多程序都是这样做的,因为它们的设计使不同的线程处理不同类型的任务(比如一个线程可以读取/写入文件,另一个线程可以控制GUI,另一个线程可能处理后台的东西,另一个线程可以与网络对话),但是它实际上不会使程序运行得更快。
https://stackoverflow.com/questions/55930628
复制相似问题