View in Telegram
​​Зачем локать мьютексы в разном порядке #новичкам Можете подумать, что раз всем так известно, что мьютексы опасно лочить в разном порядке, то почему вообще кому-то в голову может прийти наступить на грабли и накалякать такое своими программисткими пальчиками снова? Просто не пишите хреновый код и будет вам счастье. Дело в том, что иногда это не совсем очевидно. Точнее почти всегда это не очевидно. Программисты хоть и разные бывают, но ревью никто не отменял и такую броскую ошибку бы явно заметили. Поэтому не все так просто, как на первый взгляд кажется. Разберем чуть более сложный пример:
struct SomeSharedResource {
  void swap(SomeSharedResource& obj) {
    {
      std::lock_guard lg{mtx};
      // just for results reproducing
      std::this_thread::sleep_for(std::chrono::milliseconds(10));
      std::lock_guard lg1{obj.mtx};
      // handle swap
    }
  }
  std::mutex mtx;
};

int main() {
  SomeSharedResource resource1;
  SomeSharedResource resource2;  
  std::mutex m2;
  std::thread t1([&resource1, &resource2] {
    resource1.swap(resource2);
    std::cout << "1 Do some work" << std::endl;
  });
  std::thread t2([&resource1, &resource2] {
    resource2.swap(resource1);
    std::cout << "2 Do some work" << std::endl;
  });

  t1.join();  
  t2.join();
}
Все просто. У нас есть пара объектов, которые используются в качестве разделяемых ресурсов (их могут изменять более 1 потока). Объекты могут обмениваться между собой данными. Ну и по всем канонам нам же надо защитить оба объекта при свопе. Поэтому после захода в функцию обмена сначала лочим свой мьютекс, а потом мьютекс объекта с которым собираемся свопаться. И вроде снаружи кажется, что мы всегда лочим в одном порядке. Пока мы не будем обменивать данные одних и тех же объектов в разных потоках в разном порядке. Тогда первый поток может залочить мьютекс первого объекта и, допустим, заснуть. А второй поток первым залочит мьютекс второго объекта. И все. Приплыли. И это все еще может показаться детским садом и очевидушкой. Только вот сам момент взятия замка уже не выглядит так подозрительно. А сами объекты могут лежать в каких-то страшных структурах данных и могут быть разбросаны по коду. В таком случае все не так очевидно становится. В следующий раз поговорим, как же не допускать такие ошибки. Don't be obvious. Stay cool. #concurrency
Love Center
Love Center
Find friends or serious relationships easily