質問: データ型がプロシージャではなくスレッドセーフとしてマークされるのはなぜですか? rustでは、send(またはsync)マーカー特性を使用して、スレッドコンテキスト内で型の値(またはその参照)を処理できるかどうかを示します。ただし、c関数のマンページ(man 3 randなど)で頻繁に見られるように、スレッドセーフかどうかは関数またはプロシージャの属性です。では、なぜrustは、このような属性を関数ではなくデータ型に適用するように設計されているのですか?struct foo { ... } unsafe sync fn thread_safe_fn(foo: &foo) { ... } このように、どの型もどこでも使用できますが、共有データを操作できるのはsync関数だけです。これにより、たとえば、アトミック(rc)または非アトミック(!sync)のいずれかの定義済み演算を持つ単一のsyncを持つことが可能になります。
回答: 共有されるdataが変更される可能性があること、およびどのようにそのデータを保護するかを認識すること以外に、スレッドセーフを意味する関数に固有のものはありません。メモリ内に存在するデータ自体であり、個別の実行スレッドからアクセスでき、通常は関数ではありません(ロード後にコードが変更される関数がある場合を除きますが、それははるかにまれです)。 cのrand()関数の場合、その実装は共有データにアクセスし、同時アクセスから保護しません。マンページから、「関数rand()は、呼び出しごとに変更される非表示の状態を使用するため、再入可能ではありません。」言語が記述どおりに記述されている場合は、ユーティリティ関数がfooを変更する状況を考慮してください。このユーティリティ関数がスレッドセーフとしてマークされている場合、不必要にロックを取得し、(必ずしも)共有されていないデータを保護する必要があります。さらに、同じメモリ位置への同時アクセスからのスレッドのみをブロックし、関数内のすべてのエントリポイントへのアクセスをブロックしないようにします。これは、特定の部分を保護するものではなく、汎用関数が実行をシリアル化する必要がある場合に少し扱いにくくなります。データの。