fork download
  1. #include<algorithm>
  2. #include<atomic>
  3. #include<exception>
  4. #include<iostream>
  5. #include<memory>
  6. #include<stdexcept>
  7. #include<thread>
  8. #include<utility>
  9. #include<vector>
  10. using namespace std;
  11.  
  12. class thr_stack
  13. {
  14. struct Node
  15. {
  16. int data;
  17. std::shared_ptr<Node> next;
  18. Node(const std::shared_ptr<Node> &next_,int data_)
  19. :data{data_},next{next_}{}
  20. ~Node()
  21. {
  22. while(next.use_count()==1)
  23. {
  24. std::shared_ptr<Node> p{std::move(next->next)};
  25. next.reset();
  26. next=std::move(p);
  27. }
  28. }
  29. };
  30. std::shared_ptr<Node> begin_;
  31. public:
  32. void emplace(int data)
  33. {
  34. begin_=std::make_shared<Node>(begin_,data);
  35. }
  36. int pop()
  37. {
  38. std::shared_ptr<Node> node{std::atomic_load(&begin_)};
  39. while(node&&!std::atomic_compare_exchange_weak_explicit(&begin_,&node,node->next
  40. ,std::memory_order_seq_cst
  41. ,std::memory_order_seq_cst))
  42. ;
  43. if(node)
  44. return node->data;
  45. throw logic_error{"nullptr"};
  46. }
  47. };
  48.  
  49. constexpr int max_num{1000000};
  50. thr_stack stack;
  51. vector<atomic<int>> vec(max_num);
  52.  
  53. void read_test(int);
  54.  
  55. int main()
  56. {
  57. for(int i{0};i!=max_num;++i)
  58. stack.emplace(i);
  59. #if 1 //the problem here
  60. const unsigned int thread_count{std::thread::hardware_concurrency()};
  61. vector<thread> thr;
  62. for(unsigned int i{0};i!=thread_count;++i)
  63. thr.emplace_back(read_test,max_num/thread_count);
  64. for(unsigned int i{0};i!=thread_count;++i)
  65. thr[i].join();
  66. #else
  67. read_test(max_num);
  68. #endif
  69. if(all_of(begin(vec),end(vec),[](auto &val){return val==1;}))
  70. cout<<"succeed"<<endl;
  71. }
  72.  
  73. void read_test(int count)
  74. {
  75. try
  76. {
  77. for(int i{0};i!=count;++i)
  78. ++vec.at(stack.pop());
  79. }catch(const exception &e)
  80. {
  81. cerr<<e.what()<<endl; //cannot catch anything
  82. }
  83. }
Success #stdin #stdout 0.43s 67328KB
stdin
Standard input is empty
stdout
succeed