序文: この知識を理解する必要がある人は、すでにプロセス間通信とスレッド間通信の基本的な理解を持っていると思います。たとえば、プロセス間通信のメカニズムの 1 つは共有メモリです (ここでは詳しく説明しません)。複数のプロセスが同時に同じメモリ ブロックにアクセスできます。このメモリにアクセスするクリティカル セクションが相互に排他的または同期されていない場合、プロセスの実行で予期しないエラーや結果が発生する可能性があります。 次に、Linux での 3 つの一般的な排他操作、つまりロックについて学習します。 1. ミューテックス 機能:読者と作家向け。一方がロックを取得している限り、もう一方はロックを取得し続けてクリティカル セクション コードを実行することはできません。 ロックを作成します。 ミューテックスを作成するには、静的と動的の 2 つの方法があります。 POSIX は、ミューテックスを静的に初期化するためのマクロ PTHREAD_MUTEX_INITIALIZER を定義します。 方法は次のとおりです。 pthread_mutex_t ミューテックス=PTHREAD_MUTEX_INITIALIZER; LinuxThreads 実装では、pthread_mutex_t は構造体であり、PTHREAD_MUTEX_INITIALIZER は構造体定数です。 動的な方法は、pthread_mutex_init() 関数を使用してミューテックス ロックを初期化することです。API 定義は次のとおりです。 pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t*mutexattr) スレッドのミューテックスを初期化します。 mutexattr は、ミューテックス属性を指定するために使用されます (以下を参照)。NULL の場合、デフォルトの属性が使用されます。 pthread_mutex_destroy() はミューテックスをキャンセルするために使用されます。API 定義は次のとおりです。 pthread_mutex_destroy() メソッドは、ミューテックスを破棄します。 ロック操作には、主に pthread_mutex_lock() のロック、pthread_mutex_unlock() のロック解除、pthread_mutex_trylock() のロック テストが含まれます。どのタイプのロックでも、2 つの異なるスレッドが同時にロックを取得することは不可能であり、ロック解除されるまで待機する必要があります。通常のロックと適応型ロック タイプの場合、ロック解除者は同じプロセス内の任意のスレッドにすることができます。一方、エラー検出ロックは、有効にするにはロック保持者がロックを解除する必要があります。そうでない場合は EPERM が返されます。ネストされたロックの場合、ドキュメントと実装ではロック保持者がロックを解除する必要がありますが、実験結果ではそのような制限がないことが示されています。この違いはまだ説明されていません。同じプロセス内のスレッドがブロックをロックしたがロックを解除していない場合、他のスレッドはロックを取得できません。 pthread_mutex_lock(pthread_mutex_t *ミューテックス) pthread_mutex_unlock(pthread_mutex_t *ミューテックス) pthread_mutex_trylock() メソッドは、ミューテックスをロックします。 pthread_mutex_trylock() のセマンティクスは pthread_mutex_lock() のセマンティクスと似ていますが、ロックがすでに占有されている場合に待機するのではなく EBUSY を返す点が異なります。 クラス SingleTon { 公共: 静的シングルトン* getInstance() { pthread_mutex_lock(&mutex); if(mpSingle == NULL) { mpSingleTon = 新しいSingleTon(); } pthread_mutex_unlock(&mutex); mpSingleTon を返します。 } プライベート: シングルトン(){}; ~シングルトン(){pthread_mutex_desttroy(&mutex,NULL);} 静的 pthread_mutex_t ミューテックス; 静的シングルトン *mpSingleTon; } pthread_mutex_t シングルトン::mutex = PTHREAD_MUTEX_INITIALIZER; シングルトン * シングルトン::mpSingleTon = NULL; アドバンテージ: これは、複数のプロセスで共有できるメモリ空間 (整列された整数変数) で構成されます。この整数変数の値は、CPU によってアセンブリ言語で提供されるアトミック操作命令を呼び出すことによって増減でき、プロセスはその値が正の数になるまで待機できます。 ほぼすべての操作はアプリケーション空間で完了します。操作結果に矛盾があり、調停が必要な場合にのみ、オペレーティング システム カーネル空間に入って実行する必要があります。このメカニズムにより、非常に高い実行効率でロック プリミティブを使用できます。ほとんどの操作では複数のプロセス間の調停が必要ないため、ほとんどの操作は (比較的高価な) カーネル システム コールを使用せずにアプリケーション空間で実行できます。 2. 読み取り書き込みロック 特徴:読み取り/書き込みロックは、データ構造の読み取り回数が書き込み回数よりはるかに多い状況に適しています。読み取りモードでロックすると共有でき、書き込みモードでロックすると排他的になるため、読み取り/書き込みロックは共有排他ロックとも呼ばれます。 初期化と破棄: int pthread_rwlock_init(pthread_rwlock_t *制限付きrwlock, const pthread_rwlockattr_t *属性を制限します。 pthread_rwlock_t は rwlock を破棄します。 成功した場合は 0 を返し、エラーが発生した場合はエラー番号を返します。ミューテックスと同様に、読み取り/書き込みロックによって占有されているメモリを解放する前に、pthread_rwlock_destroy を介して読み取り/書き込みロックをクリーンアップし、init によって割り当てられたリソースを解放する必要があります。 読み取りと書き込み: pthread_rwlock_t は rwlock を呼び出します。 pthread_rwlock_t は rwlock を呼び出します。 pthread_rwlock_t のロックを解除します。 成功した場合は 0 を返し、エラーが発生した場合はエラー番号を返します。これらの 3 つの関数は、それぞれ読み取りロックの取得、書き込みロックの取得、ロックの解放の操作を実装します。ロックを取得するための 2 つの関数はブロッキング操作です。同様に、非ブロッキング関数は次のとおりです。 pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); 成功した場合は 0 を返し、エラーが発生した場合はエラー番号を返します。非ブロッキング ロック取得操作の場合、ロックを取得できる場合は 0 を返し、それ以外の場合はエラー EBUSY を返します。 3. スピンロック 機能:ポーリングビジー待機。 シングルコア CPU では動作しません。スピン ロックによって保護されたクリティカル セクション コードは実行中に中断できません。デッドロックを引き起こすスピンロックの本来の目的は、短時間で軽量なロックを実行することです。競合するスピン ロックにより、ロックが再び使用可能になるまで待機している間、スピン ロックを要求するスレッドがスピンすることになります (これはプロセッサ時間の無駄です)。そのため、スピン ロックは長時間保持しないでください。長時間ロックする必要がある場合は、セマフォを使用することをお勧めします。 API: 要約する 上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に一定の参考学習価値を持つことを願っています。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM を応援していただきありがとうございます。 以下もご興味があるかもしれません:
|
>>: Reactはラジオコンポーネントのサンプルコードを実装します
1. 問題Windows 上の Eclipse を使用して開発されたプロジェクトは Windows ...
ディレクトリを作成する cd /usr/local/docker/ jenkins-docker を...
1. ダウンロード2. 減圧3. パス環境変数を追加し、mysqlが配置されているbinディレクトリ...
XML/HTML コードコンテンツをクリップボードにコピー< div style = &quo...
https ベースポート 443。これはキーと呼ばれるものに使用されます。これらのことを理解せずにで...
Docker SwarmについてDocker Swarm は次の 2 つの部分で構成されます。 D...
オブジェクトがメソッドを呼び出す順序:インスタンス内にメソッドが存在しない場合は、インスタンス オブ...
Code Cloudで新しいプロジェクトtest1を作成します。 公開鍵を取得するには次のコマンドを...
1. はじめに最近、CentOS での開発には多くの不便があることがわかりました。Windows/M...
目次実生活からの例クエリが遅い最適化する方法カウント制限最大値と最小値 min&max実生活...
目次1. 問題の説明2. 問題解決1. 問題の説明Vue プロジェクトを開発する場合、作成時に誤って...
次のコマンドを使用できます: docker tag [イメージID] [名前]:[バージョン]例えば...
目次1. 問題の説明: 2. Jenkins設定のトラブルシューティング3. コードログのエンコード...
タイトルで提起された問題は、段階的に分解して解決することができます。 MySQL では KEY と ...
mysql ストアド プロシージャの概念:特定のタスク (クエリと更新) を実行できる、データベース...