gpt4 book ai didi

c++ - 线程 : Fine with 10, 崩溃 10000

转载 作者:太空宇宙 更新时间:2023-11-04 14:44:28 24 4
gpt4 key购买 nike

谁能解释一下为什么下面的代码会崩溃:

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 个线程?我是多线程的新手,根本不明白发生了什么?!

最佳答案

这将创建一个包含 10,000 个默认初始化线程的 vector :

unsigned int thread_no = 10000;
vector<thread> t(thread_no);

您遇到了“容量”和“大小”之间的差异。您不仅创建了一个大到足以容纳 10,000 个线程的 vector ,您还创建了一个 10,000 个线程的 vector

请参阅以下 ( 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 个已初始化的线程,然后是 9,990 个未启动的线程。

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 up\n";

for(auto& t : threads) {
t.join();
}

std::cout << "threads joined\n";
}

---- 编辑----

具体来说,您遇到的崩溃是试图加入一个非运行线程,http://ideone.com/OuLMyQ

#include <thread>

int main() {
std::thread t;
t.join();
return 0;
}

标准错误

terminate called after throwing an instance of 'std::system_error'
what(): Invalid argument

我指出这一点是因为你应该意识到即使是有效线程也存在竞争条件,如果你这样做的话

if (t.joinable())
t.join();

“t”有可能在测试和操作之间变得不可连接。您应该始终将 t.join() 放在 try {} 子句中。参见 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 up\n";

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 joined\n";
}

关于c++ - 线程 : Fine with 10, 崩溃 10000,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21084462/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com