Saya menemukan shared_ptr dan lemah_ptr, panjang dengan daftar, melakukan pekerjaan yang saya butuhkan. Masalah saya adalah, saya punya beberapa klien yang ingin berinteraksi dengan data internal host. Biasanya, tuan rumah memperbarui data itu sendiri, namun, jika klien memintanya, tuan rumah harus berhenti memperbarui hingga tidak ada klien yang mengakses data host. Pada saat yang sama, klien dapat meminta akses eksklusif, sehingga tidak ada klien lain, atau tuan rumah, yang dapat mengubah data host tersebut.
Bagaimana saya melakukan ini, saya membuat sebuah struct:
struct UpdateLock
{
typedef std::shared_ptr< UpdateLock > ptr;
};
Setiap klien akan memiliki anggota seperti:
UpdateLock::ptr m_myLock;
Kemudian tuan rumah akan memiliki anggota lemah_ptr untuk eksklusivitas, dan daftar lemah_ptr untuk kunci non-eksklusif:
std::weak_ptr< UpdateLock > m_exclusiveLock;
std::list< std::weak_ptr< UpdateLock > > m_locks;
Ada fungsi untuk mengaktifkan kunci, dan fungsi lainnya untuk memeriksa apakah host terkunci:
UpdateLock::ptr LockUpdate( bool exclusive );
bool IsUpdateLocked( bool exclusive ) const;
Saya menguji kunci di LockUpdate, IsUpdateLocked, dan secara berkala di rutin pembaruan host. Menguji kunci adalah sesederhana memeriksa apakah lemah_ptr kadaluarsa, dan menghapus apa pun yang kadaluwarsa dari daftar m_locks (saya hanya melakukan ini selama pembaruan host), saya dapat memeriksa apakah daftar kosong; pada saat yang sama, saya mendapatkan pembukaan kunci otomatis ketika klien me-reset shared_ptr yang mereka gunakan, yang juga terjadi ketika klien dihancurkan secara otomatis.
Efek keseluruhannya adalah, karena klien jarang memerlukan eksklusivitas (biasanya dicadangkan untuk tambahan dan penghapusan saja), sebagian besar waktu permintaan untuk LockUpdate (false), yaitu non-eksklusif, berhasil selama (! M_exclusiveLock). Dan LockUpdate (true), permintaan eksklusivitas, hanya berhasil ketika keduanya (! M_exclusiveLock) dan (m_locks.empty ()).
Antrian dapat ditambahkan untuk mengurangi antara kunci eksklusif dan non-eksklusif, namun, saya belum memiliki tabrakan sejauh ini, jadi saya bermaksud menunggu sampai itu terjadi untuk menambahkan solusi (kebanyakan jadi saya memiliki kondisi pengujian dunia nyata).
Sejauh ini ini bekerja dengan baik untuk kebutuhan saya; Saya bisa membayangkan perlunya memperluas ini, dan beberapa masalah yang mungkin timbul karena penggunaan yang diperluas, namun, ini cepat untuk diterapkan, dan hanya memerlukan sedikit kode khusus.