執行緒控制(執行緒同步 執行緒安全)

2021-08-10 17:14:15 字數 2463 閱讀 1189

一、執行緒同步

當多個控制線程共享相同的記憶體時,需要確保每個執行緒看到一致的資料。如果當某個執行緒可以去修改變數,而其他執行緒也可以去讀取或者修改這個變數的時候,就需要對這些執行緒進行同步控制,以確保它們在訪問變數的儲存內容時不會訪問到無效的數值。

同步:多程序或者多執行緒訪問臨界資源時,必須進行同步控制。多程序或者多執行緒的執行並不是完全絕對的並行執行,有可能主線程需要等待函式執行緒的某些條件的發生。

多執行緒之間有幾個特殊的臨界資源:全域性資料、堆區資料、檔案描述符  多執行緒之間公用

執行緒間同步控制的方式:

(1)訊號量

標頭檔案:    #include

獲取:int sem_init(sem_t *sem, int shared, int value);

sem:是乙個 sem_t 型別指標,指向訊號量物件

shared:表示是否能在多個程序之間共享,linux 下不支援,為 0

value:訊號量的初始值

該函式成功時返回為 0,失敗時返回為 -1

p 操作:int sem_wait(sem_t *sem);    //阻塞執行

v 操作:int sem_post(sem_t *sem);

刪除:int sem_destroy(sem_t *sem);

練習:主線程迴圈獲取使用者輸入,函式執行緒統計使用者輸入的字元個數(統計一次需要 1 秒)

**如下:

#include #include #include #include #include #include char buffer[128] = ;

pthread_mutex_t mutex;

void *pthread_count(void *arg)

printf("count = %d\n", strlen(buffer));

pthread_mutex_unlock(&mutex);

sleep(1);

} pthread_exit(null);

}void main()

sleep(1);

} pthread_exit(null);

}

執行結果如下:

(2)互斥鎖

可以通過使用 pthread 的互斥介面保護資料,確保同一時間只有乙個執行緒訪問資料。互斥量(mutex)從本質上說是一把鎖,在訪問共享資源之前對互斥量進行加鎖,在訪問完成之後釋放互斥量的鎖。對互斥量進行加鎖以後,任何其他試圖再次對互斥量進行加鎖的執行緒將會被阻塞值到當前執行緒釋放該互斥鎖。如果釋放互斥鎖時有多個執行緒阻塞,所有在該互斥鎖上的阻塞執行緒都會變成可執行狀態,第乙個變為執行狀態的執行緒可以對互斥量加鎖,其他執行緒將會看到

概念:完全控制臨界資源,如果乙個執行緒完成加鎖操作,則其他執行緒無論如何都無法再完成加鎖,也就無法對臨界資源進行訪問

初始化:int pthread_mutex_init(pthread_mutex_t *mutex, pyhread_mutex_attr_t *attr);

加鎖: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);

(3)條件變數

二、執行緒安全 ----> 可重入函式

有些庫函式會使用執行緒間共享的資料,如果沒有同步控制,執行緒操作就是不安全的,所以,我麼們使用這樣一些函式時,就必須使用其安全的版本 -----> 可重入函式

三、執行緒中 fork 的使用,鎖的變化

子程序會繼承其父程序的鎖以及其鎖的狀態,但是父程序和子程序使用的不是同意把鎖,父程序解鎖並不會影響到子程序的鎖,所以子程序有可能死鎖!!!

pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));

pthread_atfork() 函式在 fork() 之前呼叫,當呼叫 fork() 時,內部建立子程序前在父程序中會呼叫 prepare,內部建立子程序後,父程序會呼叫 parent,子程序會呼叫 child。

指定在 fork 呼叫之後,建立子程序之前,呼叫 prepare 函式,獲取所有的鎖,然後建立子程序,子程序建立以後,父程序環境中呼叫 parent 解所有的鎖,子程序環境中呼叫 child 解所有的鎖,然後 fork 函式再返回。這樣保證了在 fork 之後,子程序拿到的所都是解鎖狀態,從而避免死鎖。

Linux 執行緒控制 執行緒建立

作業系統並沒有提供執行緒控制的相關介面,大佬分裝了一套執行緒控制介面。執行緒裡我們用庫函式,所以說這套介面建立的執行緒是使用者態執行緒,並且這個使用者態執行緒在作業系統中對應了乙個輕量級程序。功能 建立 個新的執行緒 原型 int pthread create pthread t thread,co...

控制線程同步的方法

控制同步的方法 已過時 加鎖 synchronized 互斥鎖 缺點 併發效率低下 synchronized synchronized obj 對obj加鎖的同步 塊 只有拿到obj鎖標記的執行緒,才能進入對obj加鎖的同步 塊 public synchronized void m 對this加鎖的...

控制線程同步的方法

控制同步的方法 已過時 加鎖 synchronized 互斥鎖 缺點 併發效率低下 synchronized synchronized obj 對obj加鎖的同步 塊 只有拿到obj鎖標記的執行緒,才能進入對obj加鎖的同步 塊 public synchronized void m 對this加鎖的...