首頁  >  文章  >  系統教程  >  Linux多執行緒互斥:一種保證執行緒安全的同步機制

Linux多執行緒互斥:一種保證執行緒安全的同步機制

PHPz
PHPz轉載
2024-02-13 13:40:17435瀏覽

Linux系統是一種支援多任務並發執行的作業系統,它可以同時運行多個進程,從而提高系統的使用率和效率。但是,如果一個進程中有多個線程,而這些線程需要共享一些資料或資源,就可能出現資料不一致或資源競爭的問題,導致系統的錯誤或例外。為了解決這個問題,就需要使用一些同步機制,例如訊號量、條件變數、互斥量等。其中,互斥量是一種比較簡單而有效的同步機制,它可以讓一個執行緒在存取共享資料或資源時,鎖定它們,防止其他執行緒同時訪問,從而確保執行緒安全。本文將介紹Linux系統中多執行緒互斥量的互斥的方法,包括互斥量的初始化、加鎖、解鎖和銷毀等面向。

同步

同一個行程中的多個執行緒共享所在行程的記憶體資源,當多個執行緒在同一時刻同時存取同一種共享資源時,需要相互協調,以避免出現資料的不一致和覆蓋等問題,執行緒之間的協調與通訊的就叫做執行緒的同步問題, 執行緒同步的思路: 讓多個執行緒依序存取共享資源,而不是並行

互斥VS同步

  • # 互斥:是指某一資源同時只允許一個訪客對其進行訪問,具有唯一性和排它性。但互斥無法限制訪客對資源的存取順序,即存取是無序的。如果操作是原子操作,那麼天然的具有互斥
  • 同步:是指在互斥的基礎上(大多數情況),透過其它機制實現訪客對資源的有序存取。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪客同時存取資源

互斥量Mutex:

  • 本質上說就是一把鎖,提供對資源的獨佔訪問,所以Mutex主要的作用是用於互斥。互斥量使同時只能有一個執行緒存取數據,可以看做一種的0/1訊號量
  • Mutex物件的值只有0和1。分別代表了Mutex的鎖定狀態和空閒狀態:
    • 鎖定狀態:當前物件被鎖定,使用者進程/執行緒如果試圖Lock臨界資源,則進入等待;
    • # 空閒狀態:目前物件為空閒,使用者進程/執行緒可以Lock臨界資源,之後Mutex值減1變成0。
  • # Mutex建立時可以有初始值,表示Mutex建立後,是鎖定狀態還是空閒狀態。
  • 在同一個執行緒中,為了防止死鎖,系統不允許連續兩次對Mutex加鎖(系統一般會在第二次呼叫立刻返回)。也就是說,加鎖和解鎖這兩個對應的操作,需要在同一個執行緒完成。

互斥模型

#include 
pthread_mutex_t  mutex                //定义互斥锁               
pthread_mutex_init()            //初始化锁          
pthread_mutex_lock()/pthread_mutex_trylock()  ...     //加锁                  
pthread_mutex_unlock()          //解锁                        
pthread_mutex_destroy()         //销毁                        
//成功返回0,失败返回error number
#include 
int pthread_mutex_init  (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
int pthread_mutex_lock  (pthread_mutex_t *mutex);
int pthread_mutex_trylock   (pthread_mutex_t *mutex);
int pthread_mutex_unlock    (pthread_mutex_t *mutex);
int pthread_mutex_destroy   (pthread_mutex_t *mutex);

死鎖deadlock

#死鎖主要發生在有多個依賴鎖存在時,會在一個執行緒試圖與另一個執行緒沿著相反的順序鎖住互斥量時發生
黑球線程按照A->的方向使用共享資源,同時白球線程按照B->A的順序使用共享資源,不巧的是,黑球線程鎖定A資源直到獲得了釋放了的B資源,白球線程鎖定B資源直到獲得了釋放了的A資源,最後的結果就是他們都不能獲得自己想要的資源,都鎖定著對方想要的資源
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中文網其他相關文章!

陳述:
本文轉載於:lxlinux.net。如有侵權,請聯絡admin@php.cn刪除