ホームページ  >  記事  >  システムチュートリアル  >  Linux マルチスレッド ミューテックス: スレッドセーフな同期メカニズム

Linux マルチスレッド ミューテックス: スレッドセーフな同期メカニズム

PHPz
PHPz転載
2024-02-13 13:40:17368ブラウズ

Linux システムは、マルチタスクの同時実行をサポートするオペレーティング システムであり、複数のプロセスを同時に実行できるため、システムの使用率と効率が向上します。ただし、プロセス内に複数のスレッドがあり、これらのスレッドが一部のデータまたはリソースを共有する必要がある場合、データの不整合やリソースの競合が発生し、システム エラーや例外が発生する可能性があります。この問題を解決するには、セマフォ、条件変数、ミューテックスなどの同期メカニズムを使用する必要があります。その中でも、ミューテックスは比較的シンプルで効果的な同期メカニズムであり、スレッドが共有データやリソースにアクセスするときにロックして、他のスレッドが同時にアクセスすることを防ぎ、スレッドの安全性を確保します。この記事では、Linux システムにおけるマルチスレッド ミューテックスの相互排除方法 (ミューテックスの初期化、ロック、ロック解除、破棄など) を紹介します。

同期

同じプロセス内の複数のスレッドは、プロセスのメモリ リソースを共有します。複数のスレッドが同じ共有リソースに同時にアクセスする場合、データの不整合や上書きなどの問題を回避するために、それらのスレッドは相互に調整する必要があります。スレッド間の通信はスレッド同期問題と呼ばれます。スレッド同期の考え方は、複数のスレッドが共有リソースに並列ではなく順番にアクセスできるようにすることです。

相互排除 VS 同期

  • 相互排他: 特定のリソースが同時に 1 人の訪問者のみにアクセスを許可し、一意かつ排他的であることを意味します。ただし、相互排除では、訪問者がリソースにアクセスする順序を制限することはできません。つまり、アクセスには順序がありません。操作がアトミック操作の場合、当然相互排他的です
  • 同期: (ほとんどの場合) 相互排他に基づいた他のメカニズムを介した訪問者によるリソースへの秩序あるアクセスを指します。ほとんどの場合、特にリソースへのすべての書き込みが相互排他的である必要がある場合、同期ではすでに相互排他が実装されています。場合によっては、複数の訪問者が同時にリソースにアクセスできるようにすることができます

ミューテックス:

  • 基本的に、これはリソースへの排他的アクセスを提供するロックであるため、Mutex の主な機能は相互排他です。ミューテックスでは、同時に 1 つのスレッドのみがデータにアクセスでき、0/1 セマフォとみなすことができます
  • Mutex オブジェクトの値は 0 と 1 のみです。 Mutex のロック状態とアイドル状態をそれぞれ表します。
    • ロック ステータス: 現在のオブジェクトはロックされています。ユーザー プロセス/スレッドが重要なリソースをロックしようとすると、待機状態になります。
    • アイドル状態: 現在のオブジェクトはアイドル状態であり、ユーザー プロセス/スレッドが重要なリソースをロックできる場合、Mutex 値は 1 減って 0 になります。
  • ミューテックスの作成時に、ミューテックスが作成後にロック状態にあるかアイドル状態にあるかを示す初期値を設定できます。
  • 同じスレッド内では、デッドロックを防ぐために、システムはミューテックスを連続して 2 回ロックすることを許可しません (通常、システムは 2 回目の呼び出しの直後に戻ります)。言い換えれば、ロックとロック解除の 2 つの対応する操作は、同じスレッドで完了する必要があります。

ミューテックス モデル

リーリー

デッドロックデッドロック

デッドロックは主に、複数の依存ロックがある場合に発生し、あるスレッドが別のスレッドと逆の順序でミューテックスをロックしようとした場合に発生します
Black Ball スレッドが A-> の方向で共有リソースを使用し、White Ball スレッドが B->A の順序で共有リソースを使用する場合、残念ながら Black Ballスレッド ロック A リソースは解放されたリソース B を取得するまで待機し、白いボールのスレッドは解放されたリソース A を取得するまでリソース B をロックします。最終的な結果は、必要なリソースを取得できず、すべてのスレッドがリソースをロックします。相手が望んでいる
Linux マルチスレッド ミューテックス: スレッドセーフな同期メカニズム#

解决死锁:

  • 对共享资源操作前一定要获得锁
  • 完成操作后一定要释放锁
  • 尽量短的时间占用锁
  • 如果有多锁,如获得的顺序是ABC顺序,那么释放顺序也该是ABC
  • 线程错误返回时会释放它所获得的锁

例子

#include
#include
#include
#include

char* buf[5];
int pos;
//1.定义互斥量
pthread_mutex_t mutex;
void* task(void* pv){
    //3.使用互斥量进行加锁
    pthread_mutex_lock(&mutex);
    
    //4.访问共享内存
    buf[pos]=(char*)pv;
    sleep(1);
    pos++;

    //5.使用互斥量进行解锁
    pthread_mutex_unlock(&mutex);
}
main(){
    //2.初始化互斥量
    pthread_mutex_init(&mutex,NULL);

    pthread_t thread;
    pthread_create(&thread,NULL,task,(void*)"zhangfei");
    pthread_t thread2;
    pthread_create(&thread2,NULL,task,(void*)"guanyu");
    
    pthread_join(thread,NULL);
    pthread_join(thread2,NULL);

    //打印字符指针数组中的有效数据
    int i=0;
    for(i=0;iprintf("%s ",buf[i]);
    }
    printf("\n");
    //6.如果不再使用则销毁互斥量
    pthread_mutex_destroy(&mutex);
    return 0;
}

本文介绍了Linux系统中多线程互斥量的互斥的方法,包括互斥量的初始化、加锁、解锁和销毁等方面。通过了解和掌握这些知识,我们可以更好地使用互斥量来实现多线程之间的同步,提高系统的稳定性和效率。当然,Linux系统中多线程互斥量还有很多其他的特性和用法,需要我们不断地学习和研究。希望本文能给你带来一些启发和帮助。

以上がLinux マルチスレッド ミューテックス: スレッドセーフな同期メカニズムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlxlinux.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。