プロセス、スレッド、非同期イベントメカニズムに基づくプログラミングなど、並行性を実現する方法はたくさんあります。マルチスレッドプログラミングの場合、同じプロセス内の複数のスレッドが、プロセスのユーザーアドレス空間とpcなどのリソースを共有する必要があります。したがって、データの競合が発生するため、CPUによって提供される命令セットのアトミックプリミティブに依存するスレッド同期メカニズム(ロックメカニズム)またはロックフリープログラミングが必要になります。また、このセクションでは、主にLinuxシステム間のロックメカニズムについて説明します。
1ミューテックス
スレッドの実際の実行プロセスでは、同期を維持するために複数のスレッドが必要になることがよくあります。
このとき、ミューテックスロックを使用してタスクを完了することができます。ミューテックスロックの使用には、主に
pthread_mutex_init、pthread_mutex_destory、pthread_mutex_lock、pthread_mutex_unlock
これらの機能は、ロックの初期化、ロックの破棄、ロックおよびロック解除の操作を完了するために使用されます。
1.1ロックの作成
ロックは動的または静的に作成できます。マクロPTHREAD_MUTEX_INITIALIZERを使用して、ロックを静的に初期化できます。この方法で理解しやすくなります。ミューテックスはpthread_mutex_tの構造であり、このマクロは構造定数です。静的初期化ロック次のように完了することができます:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
さらに、ロックはpthread_mutex_init関数を使用して動的に作成できます。関数のプロトタイプは次のとおりです。
int pthread_mutex_init(pthread_mutex_t * mutex、const pthread_mutexattr_t * attr)
1.2ロックのプロパティ
mutex属性は、pthread_mutexattr_init(pthread_mutexattr_t * mattr)によって初期化できます。その後、他の属性設定メソッドを呼び出して、その属性を設定できます。
ミューテックスロックのスコープ:プロセスを他のプロセスと同期するか、同じプロセス内の異なるスレッド間で同期するかを指定できます。PTHREAD_PROCESS_SHAREおよびPTHREAD_PROCESS_PRIVATEに設定できます。デフォルトは後者です。これは、プロセスでロックが使用されることを意味します。使える
int pthread_mutexattr_setpshared(pthread_mutexattr_t * mattr、int pshared)
pthread_mutexattr_getpshared(pthread_mutexattr_t * mattr、int * pshared)
ロックの範囲を設定および取得するために使用されます。
ミューテックスロックの種類:次の値スペースがあります。
PTHREAD_MUTEX_TIMED_NP、これはデフォルト値であり、通常のロックです。スレッドがロックされると、ロックを要求している残りのスレッドは待機キューを形成し、ロック解除後に優先度に従ってロックを取得します。このロック戦略により、リソース割り当ての公平性が保証されます。PTHREAD_MUTEX_RECURSIVE_NP、ネストされたロックにより、同じスレッドが同じロックを複数回正常に取得し、複数のロック解除を通じてロックを解除できます。別のスレッドからのリクエストの場合、ロックスレッドのロックが解除されると再び競合します。PTHREAD_MUTEX_ERRORCHECK_NP、エラー検出ロック、同じスレッドが同じロックを要求した場合、EDEADLKを返します。それ以外の場合、アクションはPTHREAD_MUTEX_TIMED_NPタイプと同じです。これにより、複数のロックが許可されていない場合に、デッドロックの最も単純なケースが発生しないことが保証されます。PTHREAD_MUTEX_ADAPTIVE_NP、アダプティブロック、最も単純なタイプのロック。ロックが解除されるのを待ってから、再び競合します。
pthread_mutexattr_settype(pthread_mutexattr_t * attr、int type)pthread_mutexattr_gettype(pthread_mutexattr_t * attr、int * type)
ロックのタイプを取得または設定します。
1.3ロックの解除
pthread_mutex_destoryを呼び出した後、ロックによって占有されていたリソースを解放できますが、ロックは現在ロックされていないという前提があります。
1.4ロック操作
ロックの操作には、主にpthread_mutex_lock()のロック、pthread_mutex_unlock()のロック解除、pthread_mutex_trylock()のテストとロックが含まれます。
int pthread_mutex_lock(pthread_mutex_t * mutex)int pthread_mutex_unlock(pthread_mutex_t * mutex)int pthread_mutex_trylock(pthread_mutex_t * mutex) 。
1.5コードの説明:
コードの説明1:ミューテックスロックの基本的なアプリケーション
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int count = 0;
void* consume(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
printf("************************consume begin lock\n");
printf("************************consumed %d\n",count);
count++;
sleep(2);
printf("************************consume over lock\n");
pthread_mutex_unlock(&mutex);
printf("************************I'm out of pthread_mutex\n");
sleep(1);
}
return NULL;
}
void* produce( void * arg )
{
while(1)
{
pthread_mutex_lock(&mutex );
printf("product begin lock\n");
printf("produced %d\n", count);
printf("product over lock\n");
pthread_mutex_unlock(&mutex );
printf("I'm out of pthread_mutex\n");
sleep(1);
}
return NULL;
}
int main( void )
{
pthread_t thread1,thread2;
pthread_create(&thread1, NULL, &produce, NULL );
pthread_create(&thread2, NULL, &consume, NULL );
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0;
}
結果の説明:
[root @ rocket lock-free] #g ++ -g -o pthread_mutex_lockpthread_mutex_lock.cpp -lpthread
[root @ rocketロックフリー]#。/ pthread_mutex_lock
製品がロックを開始します
生成された0
製品のオーバーロック
私はpthread_mutexを使い果たしています
************************ beginlockを消費します
************************消費0
/ *途中で2秒間待っていますが、製品スレッドが実行されませんでした!* /
************************オーバーロックを消費します
************************私はpthread_mutexが不足しています
製品がロックを開始します
生産1
製品のオーバーロック
私はpthread_mutexを使い果たしています
製品がロックを開始します
生産1
製品のオーバーロック
私はpthread_mutexを使い果たしています
************************ beginlockを消費します
************************消費1
************************オーバーロックを消費します
************************私はpthread_mutexが不足しています
製品がロックを開始します
生産2
製品のオーバーロック
私はpthread_mutexを使い果たしています
************************ beginlockを消費します
************************消費2
************************オーバーロックを消費します
************************私はpthread_mutexが不足しています
コードの説明2:pthread_mutext_trylockの使用
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int count = 0;
void* consume(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
printf("************************consume begin lock\n");
printf("************************consumed %d\n",count);
count++;
sleep(2);
printf("************************consume over lock\n");
pthread_mutex_unlock(&mutex);
printf("************************I'm out of pthread_mutex\n");
sleep(1);
}
return NULL;
}
void* produce( void * arg )
{
while(1)
{
if(pthread_mutex_trylock(&mutex ) == 0)
{
printf("product begin lock\n");
printf("produced %d\n", count );
printf("product over lock\n");
pthread_mutex_unlock(&mutex);
printf("I'm out of pthread_mutex\n");
sleep(1);
}
else
{
printf("I have try!But i can`t lock the mutex!\n");
sleep(1);
}
}
return NULL;
}
int main( void )
{
pthread_t thread1,thread2;
pthread_create(&thread1, NULL, &produce, NULL );
pthread_create(&thread2, NULL, &consume, NULL );
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0;
}
結果の説明:
[root @ rocket lock-free] #g ++ -g -o pthread_mutex_trylock pthread_mutex_trylock.cpp -lpthread
[root @ rocket lock-free]#。/ pthread_mutex_trylock
************************ beginlockを消費します
************************消費0
/ * Trylockは成功せずに戻ります!* /
試してみましたが、ミューテックスをロックできません!
試してみましたが、ミューテックスをロックできません!
************************オーバーロックを消費します
************************私はpthread_mutexが不足しています
製品がロックを開始します
生産1
製品のオーバーロック
私はpthread_mutexを使い果たしています
************************ beginlockを消費します
************************消費1
試してみましたが、ミューテックスをロックできません!
試してみましたが、ミューテックスをロックできません!
************************オーバーロックを消費します
************************私はpthread_mutexが不足しています
製品がロックを開始します
生産2
製品のオーバーロック
私はpthread_mutexを使い果たしています
************************ beginlockを消費します
************************消費2
試してみましたが、ミューテックスをロックできません!
試してみましたが、ミューテックスをロックできません!
************************オーバーロックを消費します
************************私はpthread_mutexが不足しています
2読み取り/書き込みロック
読み取り/書き込みロックには3つの状態があるため、より高い並列処理を行うことができます。
2.1機能
一度に1つのスレッドだけが書き込みモードで読み取り/書き込みロックを保持できますが、複数のスレッドが同時に読み取りモードで読み取り/書き込みロックを保持できます。これは、読み取り/書き込みロックが書き込みロック状態では、ロックはロック解除されます。以前は、このロックをロックしようとしたすべてのスレッドがブロックされていました。
読み取り/書き込みロックが読み取りロック状態の場合、読み取りモードでロックしようとするすべてのスレッドがアクセスできますが、スレッドが書き込みモードでロックをロックする場合は、すべてのスレッドがロックから解放されるまでブロックする必要があります。 。
一般に、読み取り/書き込みロックが読み取りモードでロックされている場合、別のスレッドが書き込みモードでロックしようとすると、読み取り/書き込みロックは通常、後続の読み取りモードロック要求をブロックし、読み取りモードロックが占有されるのを防ぐことができます。長時間待機中書き込みモードロック要求が長時間ブロックされます。
2.2適用性
読み取り/書き込みロックは、データ構造への読み取り数が書き込み数よりもはるかに多い状況に適しています。読み取りモードでロックすると共有できるため、書き込みモードでロックすると排他的であることを意味します。したがって、読み取り/書き込みロックは共有排他ロックとも呼ばれます。
2.3APIの初期化と破棄
#include <pthread.h> int pthread_rwlock_init(pthread_rwlock_t * limit rwlock、const pthread_rwlockattr_t * limit attr); int pthread_rwlock_destroy(pthread_rwlock_t * rwlock);成功した場合は0を返し、エラーの場合はエラー番号を返します。
ミューテックスロックと同様に、読み取り/書き込みロックによって占有されているメモリを解放する前に、pthread_rwlock_destroyを介して読み取り/書き込みロックをクリーンアップし、initによって割り当てられたリソースを解放する必要があります。
2.4読み取りと書き込み
#include <pthread.h> int pthread_rwlock_rdlock(pthread_rwlock_t * rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t * rwlock); int pthread_rwlock_unlock(pthread_rwlock_t * rwlock);
これらの3つの機能は、読み取りロックの取得、書き込みロックの取得、およびロックの解放の操作を実装します。ロックを取得する2つの機能は、ブロック操作です。
同様に、非ブロッキング関数は次のとおりです。
#include <pthread.h> int pthread_rwlock_tryrdlock(pthread_rwlock_t * rwlock); int pthread_rwlock_trywrlock(pthread_rwlock_t * rwlock);
ノンブロッキングロック取得操作。取得できる場合は0を返し、そうでない場合はエラーEBUSYを返します。
2.5コードの説明
コードの説明1:読み取り/書き込みロックの基本的なアプリケーション
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <bits/pthreadtypes.h>
static pthread_rwlock_t rwlock; //读写锁对象
int count = 0;
void *thread_function_read(void *arg)
{
while(1)
{
pthread_rwlock_rdlock(&rwlock);
printf("************************%d, read count %d\n", pthread_self(), count);
sleep(1);
pthread_rwlock_unlock(&rwlock);
usleep(100);
}
return NULL;
}
void *thread_function_write(void *arg)
{
while(1)
{
pthread_rwlock_wrlock(&rwlock);
count++;
printf("************************%d, write count %d\n", pthread_self(), count);
sleep(5);
pthread_rwlock_unlock(&rwlock);
usleep(100);
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t rpthread1, rpthread2, wpthread;
pthread_rwlock_init(&rwlock,NULL);
pthread_create(&rpthread1, NULL, thread_function_read, NULL);
pthread_create(&rpthread2, NULL, thread_function_read, NULL);
pthread_create(&wpthread, NULL, thread_function_write, NULL);
pthread_join(rpthread1, NULL);
pthread_join(rpthread2, NULL);
pthread_join(wpthread, NULL);
pthread_rwlock_destroy(&rwlock);
exit(EXIT_SUCCESS);
}
結果の説明:
[root @ rocket lock-free]#。/ pthread_rwlock
/ * 2つのリーダースレッドが互いにブロックしない* /
************************ 1442944768、読み取りカウント0
************************ 1432454912、読み取りカウント0
/ *書き込みスレッドは他のすべてのスレッドをブロックします* /
************************ 1421965056、書き込みカウント1
************************ 1442944768、読み取りカウント1
************************ 1432454912、読み取りカウント1
************************ 1421965056、書き込みカウント2
************************ 1442944768、読み取りカウント2
************************ 1432454912、読み取りカウント2
************************ 1421965056、書き込みカウント3
************************ 1442944768、読み取りカウント3
************************ 1432454912、読み取りカウント3
************************ 1421965056、書き込みカウント4
興味深いのは、上記のコードのthread_function_readとthread_function_writeでusleep(100)を追加および削除すると、次の結果が表示されることです。
[root @ rocket lock-free]#。/ pthread_rwlock
************************-1896831232、読み取りカウント0
************************-1907321088、読み取りカウント0
************************-1907321088、読み取りカウント0
************************-1896831232、読み取りカウント0
************************-1907321088、読み取りカウント0
************************-1896831232、読み取りカウント0
************************-1907321088、読み取りカウント0
書き込みロックを取得できないことがわかりました。当初の理解では、リーダースレッドが最初に開始されるため、リーダーが最初にロックを取得します。リーダーがロックを取得した後、ライターはロック要求でブロックされます。リーダーがリリースされたら、ライターの番になるはずです。リーダーがリリース後に再度ロックを要求した場合でも、ロックを取得できます。作家はほとんどロックを取得できません!
マニュアルを確認して、「pthread_rwlock_rdlock()関数は、rwlockによって参照される読み取り/書き込みロックに読み取りロックを適用します。ライターがロックを保持しておらず、ロックでブロックされているライターがない場合、呼び出し元のスレッドは読み取りロックを取得します。ライターがロックを保持しておらず、ロックを待機しているライターがいるときに呼び出しスレッドがロックを取得するかどうかは指定されていません」とは、書き込みロックを待機しているライターがいない場合に、リーダーが読み取りロックを取得できることを意味します。ただし、説明はありません。ライターが書き込みロックを期待している場合は、どうすればよいですか。
幸い、Linuxには関数pthread_rwlockattr_setkind_npがあります。
列挙型
{{
PTHREAD_RWLOCK_PREFER_READER_NP、
PTHREAD_RWLOCK_PREFER_WRITER_NP、
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP、
PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_READER_NP
};
可是指定pthread_rwlockattr_setkind_np(&attr、PTHREAD_RWLOCK_PREFER_WRITER_NP);
無駄だ!どうして?マニュアルページがないので、この関数が実装されていないのではないかと思ったので、debuginfo-install glibc?を使用してglibcデバッグシンボルをインストールし、gdbをフォローアップしたところ、pthread_rwlockattr_setkind_npが実際に実装されていることがわかりました。コードは非常にsimple。Attrが変更されました。のメンバー変数。何故ですか?
もう一度グーグルで検索すると、ついにpthread_rwlockattr_setkind_npのマニュアルページが見つかりました。最後にメモがあり、汗をかきました。
「値の読み取り/書き込みロックの種類をPTHREAD_RWLOCK_PREFER_WRITER_NPに設定すると、値をPTHREAD_RWLOCK_PREFER_READER_NPに設定した場合と同じ動作になります。リーダースレッドがロックを保持している限り、書き込みロックを保持しているスレッドは飢えています。種類の値をPTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NPに設定すると、ライターを実行できます。ただし、名前が示すように、ライターは再帰的ではない場合があります。「「
その意味は、
PTHREAD_RWLOCK_PREFER_WRITER_NPとPTHREAD_RWLOCK_PREFER_READER_NPは同じです!PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NPに設定する必要があります!ただし、PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NPも名前のみで存在し、再帰的ではありません。
したがって、コードの説明2があります。読み取り/書き込みロックの優先順位の使用
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <bits/pthreadtypes.h>
static pthread_rwlock_t rwlock; //读写锁对象
int count = 0;
void *thread_function_read(void *arg)
{
while(1)
{
pthread_rwlock_rdlock(&rwlock);
printf("************************%d, read count %d\n", pthread_self(), count);
sleep(1);
pthread_rwlock_unlock(&rwlock);
//usleep(100);
}
return NULL;
}
void *thread_function_write(void *arg)
{
while(1)
{
pthread_rwlock_wrlock(&rwlock);
count++;
printf("************************%d, write count %d\n", pthread_self(), count);
sleep(1);
pthread_rwlock_unlock(&rwlock);
usleep(100);
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t rpthread1, rpthread2, wpthread;
pthread_rwlockattr_t attr;
pthread_rwlockattr_setkind_np(&attr,PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
pthread_rwlock_init(&rwlock, &attr);
pthread_create(&rpthread1, NULL, thread_function_read, NULL);
pthread_create(&rpthread2, NULL, thread_function_read, NULL);
pthread_create(&wpthread, NULL, thread_function_write, NULL);
pthread_join(rpthread1, NULL);
pthread_join(rpthread2, NULL);
pthread_join(wpthread, NULL);
pthread_rwlock_destroy(&rwlock);
exit(EXIT_SUCCESS);
}
演算結果:
[root @ rocket lock-free]#。/ pthread_rwlock_withpriority
************************ 1529054976、読み取りカウント0
************************ 1518565120、読み取りカウント0
************************ 1508075264、書き込みカウント1
************************ 1529054976、読み取りカウント1
************************ 1518565120、読み取りカウント1
************************ 1508075264、書き込みカウント2
************************ 1529054976、読み取りカウント2
************************ 1518565120、読み取りカウント2
************************ 1508075264、書き込みカウント3
これにより、作家が飢えて死ぬことはありません。
コードの説明3:pthread_rwlock_tryrdlockの使用
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <bits/pthreadtypes.h>
static pthread_rwlock_t rwlock; //读写锁对象
int count = 0;
void *thread_function_read(void *arg)
{
int print_count = 0;
while(1)
{
if (pthread_rwlock_tryrdlock(&rwlock) == 0)
{
printf("************************%d, read count %d\n", pthread_self(), count);
sleep(1);
pthread_rwlock_unlock(&rwlock);
usleep(100);
}
else
{
print_count++;
if (print_count % 10 == 0)
{
printf("I have try!But i can`t lock the rdlock!\n");
print_count = 0;
}
usleep(100);
}
}
return NULL;
}
void *thread_function_write(void *arg)
{
while(1)
{
pthread_rwlock_wrlock(&rwlock);
count++;
printf("************************%d, write count %d\n", pthread_self(), count);
sleep(5);
pthread_rwlock_unlock(&rwlock);
usleep(100);
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t rpthread1, rpthread2, wpthread;
pthread_rwlock_init(&rwlock,NULL);
pthread_create(&rpthread1, NULL, thread_function_read, NULL);
pthread_create(&rpthread2, NULL, thread_function_read, NULL);
pthread_create(&wpthread, NULL, thread_function_write, NULL);
pthread_join(rpthread1, NULL);
pthread_join(rpthread2, NULL);
pthread_join(wpthread, NULL);
pthread_rwlock_destroy(&rwlock);
exit(EXIT_SUCCESS);
}
結果の説明:
************************ 1819674368、読み取りカウント0
************************ 1809184512、読み取りカウント0
************************ 1798694656、書き込みカウント1
/ * Trylockは成功せずに戻ります!* /
試してみましたが、サードロックをロックできません!
試してみましたが、サードロックをロックできません!
試してみましたが、サードロックをロックできません!
試してみましたが、サードロックをロックできません!
************************ 1819674368、読み取りカウント1
************************ 1809184512、読み取りカウント1
************************ 1798694656、書き込みカウント2
試してみましたが、サードロックをロックできません!
試してみましたが、サードロックをロックできません!
試してみましたが、サードロックをロックできません!
試してみましたが、サードロックをロックできません!
3スピンロック
スピンロックは、SMPアーキテクチャの低レベルの同期メカニズムです。スレッドAがスピンロックを取得する必要があり、ロックが別のスレッドロックによって保持されている場合、スレッドAはループでスピンして、ロックがすでに使用可能かどうかを確認します。スピンロックの場合、次の点に注意する必要があります。
スピン中にCPUが解放されないため、スピンロックを保持しているスレッドはできるだけ早くスピンロックを解放する必要があります。そうしないと、スピンロックを待機しているスレッドが常にそこでスピンし、CPU時間を浪費します。
スピンロックを保持しているスレッドは、他のスレッドがスピンロックを取得できるように、スリープ前にスピンロックを解放する必要があります。(カーネルプログラミングでは、スピンロックを保持しているコードがスリープ状態になると、システム全体がハングする可能性があります)
Pthreadsによって提供されるスピンロック操作に関連するAPIには、主に次のものが含まれます。
intpthread_spin_destroy(pthread_spinlock_t *);
int pthread_spin_init(pthread_spinlock_t *、int);
intpthread_spin_lock(pthread_spinlock_t *);
intpthread_spin_trylock(pthread_spinlock_t *);
intpthread_spin_unlock(pthread_spinlock_t *);
3.1スピンロックを初期化する
pthread_spin_initは、スピンロックを使用するために必要なリソースを適用し、それを非ロック状態に初期化するために使用されます。psharedの値とその意味:
PTHREAD_PROCESS_SHARED:スピンロックは複数のプロセスのスレッド間で共有できます。
PTHREAD_PROCESS_PRIVATE:このスピンロックを初期化したスレッドが配置されているプロセス内のスレッドのみがスピンロックを使用できます。
3.2スピンロックを取得する
pthread_spin_lockは、指定されたスピンロックを取得(ロック)するために使用されます。スピンロックが現在他のスレッドによって保持されていない場合、関数を呼び出すスレッドはスピンロックを取得します。それ以外の場合、関数は戻る前にスピンロックを取得しません。関数を呼び出すスレッドが関数を呼び出すときにすでにスピンロックを保持している場合、結果は不確実です。
3.3スピンロックの取得を試みる
pthread_spin_trylockは、指定されたスピンロックを取得しようとします。取得できない場合は、失敗を返すことを理解します。
3.4スピンロックを解除(ロック解除)する
pthread_spin_unlockは、指定されたスピンロックを解放するために使用されます。
3.5スピンロックを破壊する
pthread_spin_destroyは、指定されたスピンロックを破棄し、関連するすべてのリソースを解放するために使用されます(いわゆるallは、pthread_spin_initによって自動的に適用されるリソースを指します)。この関数を呼び出した後、スピンロックを再初期化するためにpthread_spin_initが呼び出されない場合、ロック呼び出しの結果は未定義です。スピンロックが使用されている場合、またはこの関数が呼び出されたときにスピンロックが初期化されていない場合、結果は未定義です。
4機能の比較
ロックタイプ |
ロック特性 |
該当シーン |
---|---|---|
ミューテックス |
スレッドの切り替えが発生します |
一般的な最初の選択肢 |
読み取り/書き込みロックrwlock |
1人のライターだけが同時に複数のリーダーを持つことができます |
続きを読み、シーンを少なく書く |
スピンロック |
小さなコードセグメントに適した、CPU使用率の増加につながるスレッドスイッチングを引き起こしません |
小さなコードスニペット、ロックが頻繁ではないシナリオ |