2017-12-20 7 views
0

OSを書くために読み終えました。今、私はそれを複数のスレッドに分割しています。スレッドを持っているどのようにそれまでは待つ他はすべて

この時点では、すべてunordered_mapの周りを回転しています。マップを変更しているスレッドは1つだけです。

したがって、基本的に1つの書き込みは複数回読み込みます。

これまで書き込みでmtx.lockとmtx.unlockを実装していましたが、書き込みプロセスが行われている間は誰も読み取れません。

誰かが読んでいる間に書き込みが行われると問題が発生します。

理論的には、すべての読み取りで同じmtx.lockとmtx.unlockを置くことができ、問題を解決できるはずです。しかし、これは、私が必死に避けようとしていることです。何故なら、データが読み込まれるポイントがたくさんあり、誰かのために私にとって本当に不便な100以上のロックを実装する必要があるからです。

質問: 誰もが読み込みを完了してからロックを呼び出して書き込みを行うまで、書き込みを行っているスレッドを待機させることはできますか?もちろん、これをやり遂げるにはどうすればいいでしょう。

+0

このように、読み込みの優先度を上げたい(たとえデータが古くても)。 –

+0

はいデータが古くなっても問題ありません。スレッドを読み込み可能にする必要があります。何の問題も起こさずに。そして、すべての読み込みにロックを実装するのではなく、書き込みスレッドが誰でも読み書きを完了しているかどうかを確認できるかどうかを確認したかったのです。 – ChronicUser

+0

"理論的には、すべての読み込みに同じmtx.lockとmtx.unlockを置くことができると理解しています - 理論的には?先ほどの2段落では、「私はこれまでに読んだところにmtx.lockとmtx.unlockを実装しました」と言っています。 – MSalters

答えて

0

"誰もが読み込みを完了してロックを呼び出して書き込みを行うまで、書き込みを行っているスレッドを待機させることはできますか?"

あなたは複数の読書場所を持っているので、達成しようとしているものとは逆の意見をします。あなたが読むたびにメッセージ(ロック)を送信する必要があります。

一般的にそれは非常に悪く聞こえますが、それにもかかわらず: あなたの書き込みが偶然に起こった場合、読み込みスレッドに「ロック」メッセージを送信できます。読書スレッドは、あなたが時折書くときにメッセージ/イベントを受け取ります。スレッドを読み込むと、しばらくロックされ、メッセージを送信します(書き込むのは問題ありません)。書き込み完了後、書き込みスレッドは読み込みスレッドに通知します。読み込みには問題ありません。

Check this wiki page

+0

私はこの解決策を知っています。誰かがこの問題を回避することを知っているかどうかを見極めて、自分のロックを呼び出す前に誰かが読んでいるかどうかを調べます。だから私はただ一つの場所にロックを持つことができ、読み込みが行われる場所は本当にたくさんあり、これらの場所のすべてにロックを追加するだけで便利なので、読み込みごとにロックを実装することはできません。 – ChronicUser

0

最も簡単な解決策はstd::atomic<std::unordered_map*>かもしれません。

原子変数は、読み込み中に更新することができます。読者が古いポインタか新しいポインタかを保証することはできませんが、ランダムな値ではなく2つのうちの1つを取得します。

これは簡単ですが、1つの欠点があります。あなたが退職した旧地図deleteが安全であることをどのように知っていますか?

代替手段 - std::shared_ptr<std::unordered_map>があります。読者を読んでを読むと、グローバルポインタのプライベートコピーが作成されます。これにより、使用している地図のバージョンが確実に維持されます。ライタースレッドは、新しいマップがあるときにstd::make_sharedを呼び出し、それをグローバルポインターに割り当てます。

std::shared_ptrは、スレッドセーフですです。それを読み取るのはスレッドセーフであり、競合するライターはありません(各リーダースレッドは独自のコピーを上書きします)。

Ex。

class Writer { 
    std::shared_ptr<std::unordered_map<Foo>> m_map; 
    void add(Foo f) { 
    auto copy = std::make_shared<std::unordered_map<Foo>>(m_map); 
    copy.insert(f); 
    m_map = foo; // thread-safe 
    } 
public: 
    std::shared_ptr<std::unordered_map<Foo>> getMap() { return m_map; } 
}; 
+0

例のために私があなたを困らせる可能性はありますか?私はこれを多くの成功なしで統合しようとしてきました。 – ChronicUser

+0

@ChronicUser:added – MSalters

1

基本的には読み取り/書き込みロックです。これにより、複数の読者または1人のライターがいつでもアクセスできるようになりますが、両方にアクセスすることはできません。

これは、std::shared_mutexを使用するか、(古いC++の場合)boost::shared_mutexを使用してC++ 17で実現できます。共有ミューテックスは、2つのレベルのアクセスを許可します。共有アクセス権(読者が要求する)または排他的なアクセス権を書き込み時に要求します。

関連する問題