线程:精细10,崩溃10000
Threads: Fine with 10, Crash with 10000
有人能解释一下以下代码崩溃的原因吗:
int a(int x)
{
int s = 0;
for(int i = 0; i < 100; i++)
s += i;
return s;
}
int main()
{
unsigned int thread_no = 10000;
vector<thread> t(thread_no);
for(int i = 0; i < 10; i++)
t[i] = std::thread(a, 10);
for(thread& t_now : t)
t_now.join();
cout << "OK" << endl;
cin.get();
}
但可以使用10个线程我是多线程的新手,根本不明白发生了什么?!
这将创建10000个默认初始化线程的向量:
unsigned int thread_no = 10000;
vector<thread> t(thread_no);
您正在遇到"容量"answers"大小"之间的差异。您不仅创建了一个大到可以容纳10000个线程的向量,还创建了10000个线程的向量。
请参见以下内容(http://ideone.com/i7LBQ6)
#include <iostream>
#include <vector>
struct Foo {
Foo() { std::cout << "Foo()n"; }
};
int main() {
std::vector<Foo> f(8);
std::cout << "f.capacity() = " << f.capacity() << ", size() = " << f.size() << 'n';
}
您只将其中10个元素初始化为运行线程
for(int i = 0; i < 10; i++)
t[i] = std::thread(a, 10);
因此,for循环将看到10个初始化的线程,然后是9990个未启动的线程。
for(thread& t_now : t)
t_now.join();
您可能想尝试使用t.reserve(thread_no);
和t.emplace_back(a, 10);
下面是一个完整的重命名示例。
int threadFn(int iterations)
{
int s = 0;
for(int i = 0; i < iterations; i++)
s += i;
return s;
}
int main()
{
enum {
MaximumThreadCapacity = 10000,
DesiredInitialThreads = 10,
ThreadLoopIterations = 100,
};
vector<thread> threads;
threads.reserve(MaximumThreadCapacity);
for(int i = 0; i < DesiredInitialThreads; i++)
threads.emplace_back(threadFn, ThreadLoopIterations);
std::cout << threads.size() << " threads spun upn";
for(auto& t : threads) {
t.join();
}
std::cout << "threads joinedn";
}
----编辑----
具体来说,你遇到的崩溃是试图加入一个未运行的线程,http://ideone.com/OuLMyQ
#include <thread>
int main() {
std::thread t;
t.join();
return 0;
}
stderr
terminate called after throwing an instance of 'std::system_error'
what(): Invalid argument
我指出这一点是因为你应该意识到,即使有一个有效的线程,如果你做,也会有竞争条件
if (t.joinable())
t.join();
"t"可能在测试和操作之间变得不可连接。您应该始终在try{}子句中放入一个t.join()。看见http://en.cppreference.com/w/cpp/thread/thread/join
完整示例:
int threadFn(int iterations)
{
int s = 0;
for(int i = 0; i < iterations; i++)
s += i;
return s;
}
int main()
{
enum {
MaximumThreadCapacity = 10000,
DesiredInitialThreads = 10,
ThreadLoopIterations = 100,
};
vector<thread> threads;
threads.reserve(MaximumThreadCapacity);
for(int i = 0; i < DesiredInitialThreads; i++)
threads.emplace_back(threadFn, ThreadLoopIterations);
std::cout << threads.size() << " threads spun upn";
for(auto& t : threads) {
try {
if(t.joinable())
t.join();
} catch (std::system_error& e) {
switch (e.code()) {
case std::errc::invalid_argument:
case std::errc::no_such_process:
continue;
case std::errc::resource_deadlock_would_occur:
std::cerr << "deadlock during join - wth!n";
return e.code();
default:
std::cout << "error during join: " << e.what() << 'n';
return e.code();
}
}
}
std::cout << "threads joinedn";
}
创建一个包含10000个元素的向量,然后填充前十个元素,等待向量中的所有线程加入。您的程序崩溃是因为您忘记设置其他9990。
for(int i = 0; i < 10; i++) // Wrong
for(int i = 0; i < thread_no; i++) // Correct
相关文章:
- 当回溯以零开始时,如何调试崩溃
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 程序崩溃并显示"std::out_of_range"错误
- CoInitialize()在单独的线程上崩溃而不返回
- 使用调试/崩溃报告将应用程序部署到客户端
- 为什么所有C++编译器都会崩溃或挂起此代码
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我的多线程作业队列崩溃
- ExtractIconEx:可以工作,但偶尔会崩溃
- 为什么引用传递会导致此崩溃(C++)
- 试图创建流或fopen时程序崩溃
- 类对象数组的问题会导致崩溃
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 为什么要增加导致崩溃的指针
- 在虚幻引擎中删除NXOpen对象时崩溃
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- Visual Studio在尝试读取resource.txt文件时崩溃
- 线程:精细10,崩溃10000