在编写代码时,我注意到运行代码会返回不正确的结果,原来是我的代码中的某些部分正在更改我的协程句柄向量,我将其缩小到一行代码,在该行代码中,我用新元素覆盖了现有元素的句柄向量。
这样做还会更改向量的最后一个元素的内容(更具体地说是 myTask 标头的 bool),但不会更改中间的元素。
有人知道是什么原因导致的吗?任何帮助都感激不尽。
完整代码实现:
这样做还会更改向量的最后一个元素的内容(更具体地说是 myTask 标头的 bool),但不会更改中间的元素。
有人知道是什么原因导致的吗?任何帮助都感激不尽。
完整代码实现:
#include <concepts>
#include <coroutine>
#include <exception>
#include <iostream>
#include <myTask.h>
#include <vector>
myTask<int> getVectorInt(std::vector<int>& array, int key, bool interleave)
{
std::cout << "started lookup of key: " << key << std::endl;
int result = array.at(key);
if (interleave == true)
{
std::cout << "about to suspend task with key: " << key << std::endl;
co_await std::suspend_always{};
std::cout << "resumed task with key: " << key << std::endl;
}
co_return result;
}
void interleavedExecution(std::vector<int>& lookup, std::vector<int>& keys, std::vector<int>& results)
{
// group size = number of concurrent instruction streams
int groupsize = 3;
// initialization of handle vector
std::vector<std::coroutine_handle<myTask<int>::promise_type>> handles;
// initialization of promise vector
std::vector<myTask<int>::promise_type> promises;
// creating/initializing first handles
for (int i = 0; i < groupsize; ++i)
{
handles.push_back(getVectorInt(lookup, keys.at(i), true));
}
int notDone = groupsize;
int i = groupsize;
// interleaved execution starts here
while (notDone > 0)
{
for (int handleIndex = 0; handleIndex < handles.size(); ++handleIndex)
{
if (!handles.at(handleIndex).promise().isDone())
{
handles.at(handleIndex).resume();
handles.at(handleIndex).promise().boolIsDone = true;
}
else
{
// pushing value back directly into results
results.push_back(handles.at(handleIndex).promise().value_);
if (i < keys.size())
{
// bug here, changes the last boolIsDone also to false (or messes with the last vector element)
handles.at(handleIndex) = getVectorInt(lookup, keys.at(i), true);
handles.at(handleIndex).promise().boolIsDone = false;
++i;
}
else { --notDone; }
}
}
}
}
template <typename T>
void outputVector(std::vector<T> toOutput)
{
std::cout << "Results: ";
for (int i = 0; i < toOutput.size(); ++i)
{
std::cout << toOutput.at(i) << ' ';
}
}
int main()
{
std::vector<int> lookup = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
std::vector<int> keys = {4, 2, 0, 6, 9, 0};
std::vector<int> results;
// correct output: 50, 30, 10, 70, 100, 10
// given output: 50, 30, 70, 10, 100, 10
interleavedExecution(lookup, keys, results);
outputVector(results);
}
包含一个布尔型的myTask头:
#include <concepts>
#include <coroutine>
#include <exception>
#include <iostream>
template <typename T>
struct myTask {
struct promise_type {
unsigned value_;
~promise_type() {
//std::cout << "promise_type destroyed" << std::endl;
}
myTask<T> get_return_object() {
return myTask<T> {
.h_ = std::coroutine_handle<promise_type>::from_promise(*this)
};
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() { return {}; }
void unhandled_exception() { std::terminate(); }
std::suspend_always return_value(unsigned value) {
value_ = value;
return {};
}
bool boolIsDone = false;
auto isDone() { return boolIsDone; }
};
std::coroutine_handle<promise_type> h_;
operator std::coroutine_handle<promise_type>() const {
//std::cout << "called handle" << std::endl;
return h_; }
};
getVectorInt
函数体,并提供一个没有外部依赖的最小工作代码(minimal working code)。您能否指定所使用的编译器及其版本,因为 C++20 目前还不被许多编译器完全支持?这将有助于我们重现和定位问题。 - Jérôme Richard