STD :: async的最大线程数量是多少,将异步创建和执行
What is the maximum number of threads that std::async will create and execute asynchronously?
我有大量(>> 100k)的任务,这些任务很高(分钟),资源消耗很少。他们可能都可以并行执行它们,我正在考虑使用std::async
为每个任务生成一个未来。
我的问题是: std :: async将异步创建和执行的最大线程数是多少?(在Ubuntu 16 -XX或Centos 7.x -x86_64上使用G 6.x)
对我来说,正确的数字很重要,因为如果我没有足够的任务实际运行(等待),同时等待累积成本将很高。
要找到答案,我首先检查系统的功能:
bob@vb:~/programming/cxx/async$ ulimit -u
43735
bob@vb:~/programming/cxx/async$ cat /proc/sys/kernel/threads-max
87470
从这些数字中,我希望能够以43k线程(主要是等待)的顺序达到顺序。为了验证这一点,我编写了下面的程序,以检查使用空任务的不同线程ID的数量以及调用100K std::async
所需的时间:
#include <thread>
#include <future>
#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
#include <string>
std::thread::id foo()
{
using namespace std::chrono_literals;
//std::this_thread::sleep_for(2s);
return std::this_thread::get_id();
}
int main(int argc, char **argv)
{
if (2 != argc) exit(1);
const size_t COUNT = std::stoi(argv[1]);
std::vector<decltype(std::async(foo))> futures;
futures.reserve(COUNT);
while (futures.capacity() != futures.size())
{
futures.push_back(std::async(foo));
}
std::vector<std::thread::id> ids;
ids.reserve(futures.size());
for (auto &f: futures)
{
ids.push_back(f.get());
}
std::sort(ids.begin(), ids.end());
const auto end = std::unique(ids.begin(), ids.end());
ids.erase(end, ids.end());
std:: cerr << "COUNT: " << COUNT << ": ids.size(): " << ids.size() << std::endl;
}
时间很好,但是不同的线程ID的数量远低于预期(32748而不是43735):
bob@vb:~/programming/cxx/async$ /usr/bin/time -f "%E" ./testAsync 100000
COUNT: 100000: ids.size(): 32748
0:03.29
然后,我将foo
中的睡眠线填充以增加2s的睡眠时间。由此产生的时间与2s最多10K任务一致,但是在此外,某些任务最终共享相同的线程ID,而经过的时间则增加了2秒:
bob@vb:~/programming/cxx/async$ /usr/bin/time -f "%E" ./testAsync 10056
COUNT: 10056: ids.size(): 10056
0:02.24
bob@vb:~/programming/cxx/async$ /usr/bin/time -f "%E" ./testAsync 10057
COUNT: 10057: ids.size(): 10057
0:04.27
bob@vb:~/programming/cxx/async$ /usr/bin/time -f "%E" ./testAsync 10058
COUNT: 10058: ids.size(): 10057
0:06.28
bob@vb:~/programming/cxx/async$ ps -eT | wc -l
277
因此,看起来我的问题,在此系统上,限制为10K。我检查了另一个系统,限制为4K。
我不知道:
- 为什么这些值如此小
- 如何从系统的规格中预测这些值
带有Linux上的G ,直接答案似乎是"可以在pthread_create失败并返回eagain之前可以创建的最大线程数"。该数字可以受到几个不同的值的限制,并且man pthread_create
列出了其中3个:
- rlimit_nproc:软资源限制(我的Centos 7服务器上的4096,我的Ubuntu/virtualbox笔记本电脑上的43735)
-
/proc/sys/kernel/threads-max
的值(2061857和87470分别) -
/proc/sys/kernel/pid_max
的值(40960和32768 resp。)
systemd
至少有其他可能的限制,如man logind.conf
所示:
USERTASKSMAX =设置每个用户可以同时运行的OS任务的最大数量。这控制了tasksmax =每个用户切片单元的设置,有关详细信息,请参见SystemD.Resource-Control(5)。默认值为33%,与主机上的内核默认值等于10813,但在OS容器中可能较小。
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 复制列表初始化的隐式转换的等级是多少
- while循环中while循环的时间复杂度是多少
- 如何检查一个c++字符串中有多少相同的字符/数字
- C++有多少类型的循环
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 在条件变量中触发错误信号的频率是多少
- 函数的时间复杂度是多少?
- 必须为 C++20 协程帧保留多少内存?
- 对于四轴飞行器,PID中I控制器的理想值应该是多少
- C++,数组有多少个地址?
- 如何在C++中实现带有packaged_task的异步等待循环?
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 在 Linux 中存储区域设置名称的缓冲区大小应该是多少?
- 在内存不足之前,我可以声明多少个 const 变量?
- 可以读入进程内存的最大块大小是多少?
- 如何在不知道C++中有多少可选参数的情况下在循环中使用va_arg?
- 创建 Spdlog 异步文件记录器时遇到困难
- 在二维向量或数组中可以存储的最大元素数是多少?
- STD :: async的最大线程数量是多少,将异步创建和执行