PHPでは、 hash_copy関数を使用してハッシュコンテキスト( hashcontext )をコピーするため、元のコンテキスト状態を変更せずに同じ状態のハッシュコンピューティングインスタンスを作成できます。マルチスレッド環境でのハッシュ操作の場合、セキュリティと効率性が開発者の注意の重要なポイントです。この記事では、マルチスレッド環境におけるHASH_COPY関数のセキュリティと、ベストプラクティスの実行方法について詳しく説明します。
Hash_Copyは、ハッシュコンピューティングコンテキストをコピーするためにPHP 5.3.0で導入された関数です。
<?php
$ctx1 = hash_init('sha256');
hash_update($ctx1, 'hello');
$ctx2 = hash_copy($ctx1);
hash_update($ctx2, ' world');
echo hash_final($ctx1); // hello ハッシュ値
echo "\n";
echo hash_final($ctx2); // hello world ハッシュ値
?>
Hash_Copyは、既存のハッシュデータの計算を繰り返し回避し、コンテキストをコピーすることでパフォーマンスを向上させることができます。
PHPはマルチスレッド環境の原子ではありませんが、PthreadsやSwooleなどの拡張機能を通じてマルチスレッドを実現できます。この時点で、複数のスレッドが同じハッシュコンテキストリソースに同時にアクセスする場合があります。
Hash_Copy自体は、メモリ内の状態オブジェクトをコピーするだけです。複数のスレッドが同じコンテキスト変数を同時に共有し、ロックしない場合、読み取りと書き込みの競合が発生し、データレース条件が生じる可能性があり、したがって予測不可能なハッシュ結果が生成されます。
ただし、各スレッドがHashContextのコピーを個別に保持している場合、またはコピー後に独立して動作する場合、スレッドの安全性の問題は発生しません。
PHPハッシュエクステンションは、基礎となるC言語実装(OpenSSLまたは組み込みのハッシュライブラリ)に基づいています。通常、これらのライブラリはそれ自体がスレッドセーフですが、次のように注意を払う必要があります。
PHPまたはハッシュエクステンションの異なるバージョンには、異なるスレッド安全保証があります。
ユーザーモード共有変数は、ミューテックスまたはその他の同期メカニズムを通じて、自分で保護する必要があります。
Hash_Copy関数自体は安全ですが、複数のスレッドに複数のスレッドが同じハッシュコンテキストインスタンスを同時に動作させない場合のみです。コピーされたコンテキストは、各スレッドで個別に使用できます。
ハッシュレプリケーションがマルチスレッド環境で安全で効率的であることを確認するために、次のプラクティスが推奨されます。
ハッシュコンテキストを初期化した後、 hash_copyを介してコピーし、競争を避けるために単独で使用するために各スレッドに渡します。
<?php
$ctx = hash_init('sha256');
hash_update($ctx, 'common part data');
$threads = [];
for ($i = 0; $i < 5; $i++) {
$threadCtx = hash_copy($ctx); // 各スレッドは独立したコピーを取得します
// ここで、スレッドを作成して渡しましょう$threadCtx
// スレッド内を続けます hash_update そして最後に hash_final
}
?>
複数のスレッドが同じコンテキストを更新する必要がある場合、Mutex保護を使用する必要があります。
<?php
$mutex = new Mutex();
function safe_hash_update($ctx, $data, $mutex) {
$mutex->lock();
hash_update($ctx, $data);
$mutex->unlock();
}
?>
ただし、頻繁にロック操作がパフォーマンスに影響し、推奨されません。
非開催されていないハッシュコンテキストポインターを通過すると、人種の問題が発生します。新しいコピーは、常にhash_copyで生成する必要があります。
環境が許可されている場合は、コンテキスト状態共有によって引き起こされる複雑さを回避するために、チャンキング計算のために、ステートレスハッシュ関数( hash( 'sha256'、$ dataなど)を直接使用できます。
Hash_Copy機能自体は安全であり、マルチスレッドの安全性の危険は導入されません。
マルチスレッド環境では、同じHashContextインスタンスを共有および操作する複数のスレッドを回避することが重要です。
ベストプラクティスは、コンテキストをコピーした後、独立した使用のために各スレッドに引き渡されるか、ロックメカニズムを介して共有コンテキストを保護するためです。
可能であれば、ステートレスハッシュインターフェイスを使用してマルチスレッドを簡素化してください。