繁体   English   中英

std :: thread最大并发线程数

[英]std::thread maximum concurrent threads

我试图了解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;
} 

您似乎对上下文中“线程”的含义感到困惑。 线程有两种: std::thread软件线程 ,而std::thread::hardware_concurrency()返回硬件线程的数量。

软件线程不需要专用的硬件线程,操作系统可以并且将调度不同的软件线程来共享相同的硬件线程。 实际上,软件线程通常比计算机上的硬件线程多几个数量级。

在任何给定时间,您的计算机上都会运行数千个线程。 它们大多数来自其他程序或进程,其中有数百或数千在后台运行。 (如果您在Windows中打开TaskManager或在Linux命令提示符下键入htop ,则可以看到它们)。

那么什么是std::thread::hardware_concurrency 它是可以同时执行的线程数。 如果您有8个逻辑核心,则只能同时执行8个线程。 所有其他线程都被“暂停”,至少直到轮到它们运行为止。

这听起来像是一个矛盾:怎么可能有数千个线程而没有数千个内核? 答案是操作系统调度线程。 每个活动线程都会轮流运行,并且发生得足够快,以至于人们不会注意到延迟,但是这些线程实际上并没有同时执行。

基本上, std::thread::hardware_concurrency告诉您使用线程的最大可能速度。 如果您有8个核心,则使用线程并行化的最大速度为8倍。 可以启动更多的线程,这是很好的,许多程序这样做是因为它们被设计为使不同的线程可以处理不同类型的任务(例如一个线程可以读取/写入文件,另一个线程可以控制GUI,另一个线程可以处理)。在后台运行,并且另一个线程可能会与网络通信),但实际上并不会使您的程序运行得更快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM