C++ 使用未来的c++;
在运行时,我在代码段末尾的注释指令上遇到了分段错误。 我是否正确使用了未来?队列在单线程中工作(似乎工作)良好。当我尝试异步弹出元素时,会出现分段错误C++ 使用未来的c++;,c++,multithreading,c++11,future,C++,Multithreading,C++11,Future,在运行时,我在代码段末尾的注释指令上遇到了分段错误。 我是否正确使用了未来?队列在单线程中工作(似乎工作)良好。当我尝试异步弹出元素时,会出现分段错误 #include <iostream> #include <memory> #include <atomic> #include <thread> #include <future> #include <assert.h> using std::cout; template
#include <iostream>
#include <memory>
#include <atomic>
#include <thread>
#include <future>
#include <assert.h>
using std::cout;
template<typename T>
class Queue
{ private:
struct element
{
T data;
element* previous;
element():previous(nullptr){}
};
std::atomic<element*> head;
std::atomic<element*> tail;
public:
Queue():head(new element), tail( head.load() ){}
~Queue()
{
while( element* const old_head = head.load() )
{
head.store(old_head->previous);
delete old_head;
}
}
T* pop()
{
element* old_head = head.load();
if( old_head == tail.load() ){return nullptr;}
head.store( old_head->previous );
T* const result = new T(old_head->data);
delete old_head;
return result;
}
void push(T new_value)
{
element* new_data = new element;
new_data->data = new_value;
element* const old_tail = tail.load();
std::swap(old_tail->data, new_value);
element* p = new element;
old_tail -> previous = p;
tail.store(p);
assert( tail.load() != head.load() );
}
};
int main()
{
Queue<double> aDoubleQueue;
assert( nullptr == aDoubleQueue.pop() );
aDoubleQueue.push(17.0);
assert( 17.0 == *aDoubleQueue.pop() );
aDoubleQueue.push(17.0);
aDoubleQueue.push(19.0);
assert( 17.0 == *aDoubleQueue.pop() );
assert( 19.0 == *aDoubleQueue.pop() );
assert( nullptr == aDoubleQueue.pop() );
aDoubleQueue.push(17.0);
std::future< double* > popped = std::async(&Queue<double>::pop, &aDoubleQueue );
popped.wait();
if( nullptr == popped.get()){ cout << "\n nullptr";}
else
{ cout << "\n !nullptr";
// double* a = popped.get(); // causes a segmentation fault
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
使用std::cout;
模板
类队列
{私人:
结构元素
{
T数据;
元素*先前;
元素():previous(nullptr){}
};
原子头;
原子尾;
公众:
Queue():head(新元素),tail(head.load()){}
~Queue()
{
while(元素*const old_head=head.load())
{
店面(旧店面->旧店面);
删除旧头;
}
}
T*pop()
{
元素*old_head=head.load();
if(old_head==tail.load()){return nullptr;}
店面(旧店面->旧店面);
T*const result=新T(旧头->数据);
删除旧头;
返回结果;
}
无效推送(T新值)
{
元素*新数据=新元素;
新建_数据->数据=新建_值;
元素*const old_tail=tail.load();
交换(旧尾翼->数据,新尾翼值);
元素*p=新元素;
旧尾巴->上一个=p;
尾库(p);
断言(tail.load()!=head.load());
}
};
int main()
{
队列;双列队列;
断言(nullptr==aDoubleQueue.pop());
aDoubleQueue.push(17.0);
断言(17.0==*aDoubleQueue.pop());
aDoubleQueue.push(17.0);
aDoubleQueue.push(19.0);
断言(17.0==*aDoubleQueue.pop());
断言(19.0==*aDoubleQueue.pop());
断言(nullptr==aDoubleQueue.pop());
aDoubleQueue.push(17.0);
std::futurepopped=std::async(&Queue::pop,&aDoubleQueue);
等一下;
如果(nullptr==popped.get()){coutsay的文档
以后每次最多调用一次此成员函数
您调用它两次,此时它无效。它会抛出一个您无法处理的异常。例如
以后每次最多调用一次此成员函数
您调用它两次,此时它无效。它会抛出一个您无法处理的异常。例如
以后每次最多调用一次此成员函数
您调用它两次,此时它无效。它会抛出一个您无法处理的异常。例如
以后每次最多调用一次此成员函数
您调用它两次,此时它是无效的。它会抛出一个您无法处理的异常。根据cppreference,调用future::get()后,valid
为false
方法。第二次调用导致引发异常,因为在第一次调用后,valid
被设置为false
。根据cppreference,调用future::get()后,valid
是false
)
方法。第二次调用导致引发异常,因为在第一次调用后,valid
被设置为false
。根据cppreference,调用future::get()后,valid
是false
)
方法。第二次调用导致引发异常,因为在第一次调用后,valid
被设置为false
。根据cppreference,调用future::get()后,valid
是false
)
方法。第二次调用导致引发异常,因为在第一次调用后,valid
设置为false
。我也是期货新手。因此我可能会退出。
您需要poppedc.wait()吗
我的理解是popped.get会自动等待
正如前面所指出的,您不应该调用get两次。我的想法是在第二个get上设置一个断点,并在代码中单步执行以查看segfault。我敢打赌,get尝试返回指向已删除数据的指针
使用队列是安全的,但很危险。最简单的解释是,线程中没有对队列的交叉访问
对击中的反应。
否。线程1运行到启动线程2,线程1立即停止。线程2运行到完成。然后线程1再次启动。不可能存在争用条件,因为流将不允许它。我也是期货新手。因此我可能会退出。
您需要poppedc.wait()吗
我的理解是popped.get会自动等待
正如前面所指出的,您不应该调用get两次。我的想法是在第二个get上设置一个断点,并在代码中单步执行以查看segfault。我敢打赌,get尝试返回指向已删除数据的指针
使用队列是安全的,但很危险。最简单的解释是,线程中没有对队列的交叉访问
对击中的反应。
否。线程1运行到启动线程2,线程1立即停止。线程2运行到完成。然后线程1再次启动。不可能存在争用条件,因为流将不允许它。我也是期货新手。因此我可能会退出。
您需要poppedc.wait()吗
我的理解是popped.get会自动等待
正如前面所指出的,您不应该调用get两次。我的想法是在第二个get上设置一个断点,并在代码中单步执行以查看segfault。我敢打赌,get尝试返回指向已删除数据的指针
使用队列是安全的,但很危险。最简单的解释是,线程中没有对队列的交叉访问
对击中的反应。
否。线程1运行到启动线程2,线程1立即停止。线程2运行到完成。然后线程1再次启动。不可能存在争用条件,因为f