lundi 22 novembre 2021

Why shared_ptr object works well without lock in such case?

One reader thread & multi writer threads concurrently access shared_ptr object and it works well, code as below (BUT, if i modify the write line code from "=" to "reset", it will coredump while reading) :

shared_ptr.reset means coredump and "operator =" means works well ? ( I tried more than 100 times)

bool start = false;
std::mutex mtx;
std::condition_variable cond;
std::shared_ptr<std::string> string_ptr(new std::string("hello"));

int main() {
  auto read = []() {
    {
      std::cout << "readddd" << std::endl;
      std::unique_lock<std::mutex> lck(mtx);
      while (!start) {
        cond.wait(lck);
      }
    }
    for (int i = 0; i < 100000; ++i) {
      std::cout << *string_ptr.get() << std::endl;
    }
  };

  auto write = []() {
    {
      std::unique_lock<std::mutex> lck(mtx);
      while (!start) {
        cond.wait(lck);
      }
    }
    for (int i = 0; i < 100000; ++i) {
      string_ptr = std::make_shared<std::string>(std::to_string(i));
      // string_ptr.reset(new std::string(std::to_string(i))); // will coredump
    }
  };

  std::thread w(write);
  std::thread rthreads[20];

  for (int i = 0; i < 20; ++i) {
    rthreads[i] = std::thread(read);
  }

  {
    std::unique_lock<std::mutex> lck(mtx);
    start = true;
    cond.notify_all();
  }

  w.join();
  for (auto& t : rthreads) {
    t.join();
  }

  return 0;
}

coredumpe stack will be :

#0 0x00007fee5fca3113 in std::basic_ostream<char, std::char_traits >& std::operator<< <char, std::char_traits, std::allocator >(std::basic_ostream<char, std::char_traits >&, std::basic_string<char, std::char_traits, std::allocator > const&) () from /lib64/libstdc++.so.6 #1 0x00000000004039f0 in <lambda()>::operator()(void) const (__closure=0xa54f98) at test_cast.cpp:395

line "std::cout << *string_ptr.get() << std::endl;"

Aucun commentaire:

Enregistrer un commentaire