fork(1) download
  1. #include <vector>
  2. #include <chrono>
  3. #include <atomic>
  4. #include <thread>
  5. #include <cassert>
  6. #include <iostream>
  7.  
  8. struct list {
  9. struct node {
  10. std::atomic<node*> next;
  11.  
  12. void start_operation() {
  13. static std::atomic_int i;
  14. ++i;
  15. int j = i;
  16. using namespace std::literals;
  17. std::this_thread::sleep_for((rand()%100/100.)*.01s);
  18. std::cerr <<"doing it! i="<<j<<"\n";
  19. assert(i == 1);
  20. --i;
  21. }
  22. };
  23.  
  24. std::atomic<node*> tail{ nullptr };
  25.  
  26. void push(node* new_node) {
  27. using namespace std::literals;
  28.  
  29. std::this_thread::sleep_for((rand()%100/100.)*.2s);
  30.  
  31. node* old_tail = tail.exchange(new_node);
  32.  
  33. std::this_thread::sleep_for((rand()%100/100.)*.2s);
  34.  
  35. if(old_tail == nullptr || old_tail->next.exchange(new_node) == old_tail) {
  36. node* current = new_node;
  37. while(true) {
  38. current->start_operation();
  39. std::this_thread::sleep_for((rand()%100/100.)*0.01s);
  40. node* expected = nullptr;
  41. if(current->next.compare_exchange_strong(expected, new_node)) return;
  42. else current = expected;
  43. }
  44. }
  45. }
  46. };
  47.  
  48. int main() {
  49. srand(1);
  50. list l;
  51. std::vector<std::thread> ts;
  52. for (int i=0; i<10; ++i) {
  53. ts.emplace_back([&l,i]() {
  54. list::node n;
  55. std::string s="push "+std::to_string(i)+"\n";
  56. std::cerr << s;
  57. l.push(&n);
  58. s="finished "+std::to_string(i)+"\n";
  59. std::cerr << s;
  60. using namespace std::literals;
  61. std::this_thread::sleep_for(1s);
  62. });
  63. }
  64. for (auto& t : ts)
  65. t.join();
  66. std::cerr << "done\n";
  67. }
  68.  
Success #stdin #stdout #stderr 0s 51544KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
push 3
push 4
push 5
push 6
push 7
push 8
push 9
push 2
push 1
push 0
finished 0
doing it! i=1
doing it! i=1
finished 6
finished 4
finished 1
finished 7
finished 8
finished 5
finished 9
finished 3
finished 2
done