Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用未来的c++;_C++_Multithreading_C++11_Future - Fatal编程技术网

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