由于移动的承诺而导致的分段错误
Segmentation fault because of moved promise
我已经通过一个承诺作为对线程的引用。之后,通过 std::move 将 promise 移动到 vector 中。这导致软件执行时出现段错误。
我估计线程中的引用在移动 promise 后从未更新过?我怎样才能将承诺传递给线程,以便我可以在之后移动它?请查看我的问题的以下代码示例。
#include <iostream>
#include <thread>
#include <vector>
#include <future>
class Test {
public:
std::thread t;
std::promise<int> p;
Test(std::thread&& rt, std::promise<int>&& rp) : t(std::move(rt)), p(std::move(rp)) {}
};
int main()
{
std::vector<Test> tests;
{
auto p = std::promise<int>();
std::thread t ([&p]{
std::cout << 1;
p.set_value(1);
});
tests.push_back(Test(std::move(t), std::move(p)));
}
for(Test& mytest : tests)
{
mytest.t.join();
}
}
我没有回答你的问题。至少,我还有none。但是,似乎还没有其他答案出现,我觉得你的问题很有趣,所以让我们试试这个:
#include <iostream>
#include <thread>
#include <vector>
#include <future>
#include <memory>
class Test {
public:
std::thread t;
std::unique_ptr<std::promise<int>> pp;
Test(std::thread&& rt, std::unique_ptr<std::promise<int>>&& rpp)
: t(std::move(rt)), pp(std::move(rpp)) {}
};
int main()
{
std::vector<Test> tests;
{
auto pp = std::make_unique<std::promise<int>>();
std::thread t ([&pp]{
std::cout << 1;
pp->set_value(1);
});
tests.push_back(Test(std::move(t), std::move(pp)));
}
for(Test& mytest : tests)
{
mytest.t.join();
}
}
你看到我在那里做了什么吗?我通过智能指针间接获得了 promise 的所有权。我们知道智能指针会优雅地析构,因此承诺本身永远不会被这段代码移动,而只会移动指向承诺的指针。然而代码仍然存在段错误。
那么我们确定 promise 实际上是导致段错误的原因吗?
也许 promise 确实导致了段错误,但现在至少我们有另一种方法来解决这个问题——除非你已经尝试过了。
lambda 持有引用的承诺 p
已从 移动并且 超出范围。您将需要一个额外的间接级别,以便 promise 永远不会移动。
auto pp = std::make_unique<std::promise<int>>();
std::thread t ([p = pp.get()] { // <--- p is a promise<int>*
std::cout << 1;
p->set_value(1);
});
这样,承诺永远不会移动,您只需移动指针即可。 lambda 获得一个指向承诺的常规非拥有指针。
看到了here.
我已经通过一个承诺作为对线程的引用。之后,通过 std::move 将 promise 移动到 vector 中。这导致软件执行时出现段错误。
我估计线程中的引用在移动 promise 后从未更新过?我怎样才能将承诺传递给线程,以便我可以在之后移动它?请查看我的问题的以下代码示例。
#include <iostream>
#include <thread>
#include <vector>
#include <future>
class Test {
public:
std::thread t;
std::promise<int> p;
Test(std::thread&& rt, std::promise<int>&& rp) : t(std::move(rt)), p(std::move(rp)) {}
};
int main()
{
std::vector<Test> tests;
{
auto p = std::promise<int>();
std::thread t ([&p]{
std::cout << 1;
p.set_value(1);
});
tests.push_back(Test(std::move(t), std::move(p)));
}
for(Test& mytest : tests)
{
mytest.t.join();
}
}
我没有回答你的问题。至少,我还有none。但是,似乎还没有其他答案出现,我觉得你的问题很有趣,所以让我们试试这个:
#include <iostream>
#include <thread>
#include <vector>
#include <future>
#include <memory>
class Test {
public:
std::thread t;
std::unique_ptr<std::promise<int>> pp;
Test(std::thread&& rt, std::unique_ptr<std::promise<int>>&& rpp)
: t(std::move(rt)), pp(std::move(rpp)) {}
};
int main()
{
std::vector<Test> tests;
{
auto pp = std::make_unique<std::promise<int>>();
std::thread t ([&pp]{
std::cout << 1;
pp->set_value(1);
});
tests.push_back(Test(std::move(t), std::move(pp)));
}
for(Test& mytest : tests)
{
mytest.t.join();
}
}
你看到我在那里做了什么吗?我通过智能指针间接获得了 promise 的所有权。我们知道智能指针会优雅地析构,因此承诺本身永远不会被这段代码移动,而只会移动指向承诺的指针。然而代码仍然存在段错误。
那么我们确定 promise 实际上是导致段错误的原因吗?
也许 promise 确实导致了段错误,但现在至少我们有另一种方法来解决这个问题——除非你已经尝试过了。
lambda 持有引用的承诺 p
已从 移动并且 超出范围。您将需要一个额外的间接级别,以便 promise 永远不会移动。
auto pp = std::make_unique<std::promise<int>>();
std::thread t ([p = pp.get()] { // <--- p is a promise<int>*
std::cout << 1;
p->set_value(1);
});
这样,承诺永远不会移动,您只需移动指针即可。 lambda 获得一个指向承诺的常规非拥有指针。
看到了here.