前書き
この記事は、スレッド同期の相互排除である11番目の記事です。プロセス同期とスレッド同期の方法については、前の「コンピューターオペレーティングシステムの基本(4)-プロセス管理のプロセス同期」で説明しました。この記事はスレッドの1つです。同期方法。One- Mutex。スレッドの同期とプロセスの同期に関する次の記事を理解しやすくするために、「コンピューターのオペレーティングシステムの基本(4)-プロセスの管理とプロセスの同期」の記事を確認することをお勧めします。
ミューテックス
プロセス同期に関する記事では、プロデューサーモデルとコンシューマーモデルが紹介されました。このモデルでは、それぞれプロデューサーとコンシューマーとして機能する2つのスレッドがあります。同時実行の場合、これら2つのスレッドは同時に動作する可能性があります。重要なリソース、重要なリソースを同時に操作すると、スレッド同期の問題が発生する可能性があります。Mutexはスレッド同期を解決する方法の1つです。
ミューテックスはこの問題をどのように解決しますか?
ミューテックスは、スレッド1などのスレッドが重要なリソースを操作しているときに、他のスレッドが重要なリソースにアクセスするのを防ぐことができるようにすることです。これがミューテックスの動作原理です。
以前のプロデューサーおよびコンシューマーモデルでは、スレッド同期の最も基本的な理由は実際には次のとおりです。2つのスレッドの命令が横方向に実行され、ミューテックスは2つのスレッドの命令が横方向に実行されないようにすることができます。
実際、ミューテックスの効果はアトミック性とも呼ばれます。ミューテックスは実際にこれらの重要な命令のアトミック性を保証します。Atomicityは次のとおりです。
- アトミシティとは、一連の操作の中断できない特性を指します
- この一連の操作は、すべて実行されるか、実行されないかのいずれかです。
- 部分的な実行と部分的な非実行はありません
たとえば、現在のプロデューサーの操作。プロデューサーの操作は3つの命令に分割されます。原子性の特性に応じて、これら3つの命令はすべて実行されるか、実行されません。1つまたは2つはCPUがありません。実行されます。
- ミューテックスは最も単純なスレッド同期方法です
- ミューテックス(相互排他ロック)、2つの状態のいずれかの変数:ロック解除とロック
- 2つの状態により、リソースアクセスのシリアル化を保証できます(リソースがロックされている場合、つまり、リソースが特定のスレッドによって使用されている場合、別のスレッドがこのリソースを使用する場合は、それを使用しているリソースのみを待機できます。スレッドはリソースを解放し、別のスレッドがリソースを使用できるため、リソースアクセスのシリアル化が保証されます)
ミューテックスロックのコード例
未使用のミューテックス
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
$include<vector>
//临界资源
int num=0;
//生产者
void *producer(void*){
int times = 100000000;//循环一百万次
while(times--){
num += 1;//每次生产一个产品
}
}
//消费者
void *comsumer(void*){
int times = 100000000;
while(times--){
num -= 1;//每次消费一个产品
}
}
int main()
{
printf("Start in main function.");
//定义两个线程
pthread_t thread1,thread2;
//一个执行生成者逻辑,一个执行消费者逻辑
pthread_create(&thread1, NULL, &producer, NULL);
pthread_create(&thread2, NULL, &comsumer, NULL);
pthread_join(&thread1, NULL);
pthread_join(&thread2, NULL);
//打印临界资源的值
printf("Print in main function: num = %d\n", num);
}
動作結果:
プロデューサーとコンシューマーのサイクルタイムは同じですが、numの実行結果は0ではないため、プロデューサーとコンシューマーの問題が発生します。ミューテックスを介してこの問題を解決します
ミューテックスを使用する
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
$include<vector>
//初始化互斥量
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
//临界资源
int num=0;
//生产者
void *producer(void*){
int times = 100000000;//循环一百万次
while(times--){
//加锁
pthread_mutex_lock(&mutex);
num += 1;//每次生产一个产品
//解锁
pthread_mutex_unlock(&mutex);
}
}
//消费者
void *comsumer(void*){
int times = 100000000;
while(times--){
//加锁
pthread_mutex_lock(&mutex);
num -= 1;//每次消费一个产品
//解锁
pthread_mutex_unlock(&mutex);
}
}
int main()
{
printf("Start in main function.");
//定义两个线程
pthread_t thread1,thread2;
//一个执行生成者逻辑,一个执行消费者逻辑
pthread_create(&thread1, NULL, &producer, NULL);
pthread_create(&thread2, NULL, &comsumer, NULL);
pthread_join(&thread1, NULL);
pthread_join(&thread2, NULL);
//打印临界资源的值
printf("Print in main function: num = %d\n", num);
}
動作結果:
結果は0であり、ミューテックスの追加が効果的であることを示しています。ロックすると、実際にはコードの実行時間が長くなることがわかります。これは、ロックするとパフォーマンスが低下するためです。
これはミューテックスの内容です。例はC言語で書かれています。さまざまな言語でミューテックスを提供するAPIがあります。PHPのミューテックスAPIはここにあります:https://www.php.net/ mutex
急速に変化するテクノロジーの常識を見つけることは、技術者のコアコンピタンスです。理論と実践を組み合わせた知識と行動の統一