web-dev-qa-db-ja.com

マルチスレッド環境で他のユーザーが非スレッドセーフ変数を使用しないようにするにはどうすればよいですか?

元々シングルスレッドであったC++で記述されたアプリケーションがありますが、このプロジェクトの複雑さが増しているため、少なくとも2つまたは3つのスレッドに拡張する必要があります。

複数のスレッドスレッド間で使用される変数は合計で4つしかないため、everything thread-safeにするのは無意味です。明白な解決策は、各変数のミューテックスを作成し、私の人生を続けることです。

しかし、振り返ってみると、これは恐ろしい考えのようです!別のプログラマーがメソッドと変数の大部分がスレッドセーフではなく、別のスレッドで変数を使用していることを忘れているかもしれません。

私はこのプロジェクトのメインプログラマなので、これが問題になるとは思われませんが、正直に言って、これは悪いプログラミングであり、本当に厄介だと感じています。

どの変数がどのスレッドに対応しているかを簡単に識別できるように、変数を別々に保ついくつかの方法は何ですか?他のグローバル変数にアクセスできないようにスレッドのコードを分離することを考えていました(バグをサイレントに作成する代わりにコンパイルエラーを発生させます)。スレッドごとに名前空間またはクラスを作成することもできます。このためのベストプラクティスはありますか?

7

この問題には2つの要素があります:#1マルチスレッドをサポートするための既存のコードベースへの技術的な変更、および#2コード内のスレッドの安全性を認識するために会社の文化を変更すること。

1つ目は比較的単純です。まず、スレッドセーフでスレッドセーフではないクラスの関数をドキュメント化します。私は Jeffery Thomas に同意します。これを主要な新機能として扱う必要があります。多くの場合、スレッドセーフな完全に新しいクラスをいくつか(元のクラスとの関係でDRYに保つ)作成します。 c ++には明示的な「スレッドセーフ」タグはありませんが、クラスconstを正しくすることは、多くの助けになると思います。また、スレッドセーフかどうかを明確に文書化する必要があります(規約に従い、一貫性を保ち、想定される状態をスレッドセーフにしないでください)。

より大きな問題は、会社の文化を変えて、全員がスレッドの安全性を確実に意識できるようにすることです。これは、スタイルガイドやコードレビューなどが非常に役立つ場合がある場所です。スタイルガイドは、スレッドセーフであるとマークする方法を人々に正確に知らせることができます。私たちは多くのCプログラミングを行っているので、名前を装飾するのは苦手ですが、自分に合ったスタイルを選択する必要があります。一部の企業は、デフォルトですべてをスレッドセーフにすることに傾倒していますが、これにより、不要なコードの複雑さが大幅に増加する傾向があり、重要ではないオーバーヘッドが追加される場合があります。

コードレビューは、正しく行われると、スタイルについてすべての人を教育し、プログラミング全般に関する情報を伝える方法です。

3
IdeaHat

変数へのすべてのアクセスをスレッドセーフ関数にラップして、コードの任意の場所からの変数へのアクセスが単一のメソッドを介して流れるようにし、変数をプライベートにします。

このようにして、クラスの外部から変数にアクセスすると、スレッドセーフになります。

次のステップでは、変数を独自のクラスに移動します。安全なメソッドを介してのみアクセスできます。 (変数ごとに1つのクラスではなく、別のクラスのすべての変数のみ。)

他のプログラマーがコードをめちゃくちゃにする方法は常にありますが、私の経験では、コードを記述して、彼らが行う最も簡単なことは安全な方法であり、それが彼らの仕事になるでしょう。

5
SumGuy

マルチスレッドの追加は、クラスの主要な新機能です。私はあなたがそれを主要な新機能のように扱うべきだと思います、そしてそれをこっそり入れようとしないでください。

クラスとその関係を再考し、リファクタリングします。スレッド化された各タスクや機能のスライスを表す新しいクラスの作成を検討します。

必要に応じて、古いクラスインターフェイスをクラスの新しいクラスターへのプロキシとして保持できます。

3
Jeffery Thomas

いくつかの作業の後、私は実際にこの問題の簡単な解決策を見つけました(彼らが得るのと同じくらい簡単です)...namespaces

各論理スレッドを特定の名前空間に編成しています。たとえば、これは私の名前空間構成がどのように見えるかです(明らかに、異なるファイルに分割されています)。私がもっとたくさんのものを共有していたら、SumGuyの答え共有変数の場合ですが、4つの変数に加えてスレッドが独立しているため、すべてのコードに対してこれを行うのはやり過ぎです。

namespace MainThread {

}

namespace ThreadOne {

}

これはきれいな解決策ではありませんが、少なくとも別の人が別のスレッドで変数/関数を使用するには、Wordの「スレッド」を明示的に入力する必要があるため、このような明らかなことを無視するのは彼らの責任です。

また、1つの名前空間でコードを編集する場合、現在のスレッドの名前を自動的に想定しているため、現在のスレッドの名前を入力する手間がかかりません。

1