什么是線程
線程的定義
? ? ? ? 是輕量級的進程,可以實現多任務的并發。線程是操作系統任務調度的最小單位
線程的創建
????????由某個進程創建,且進程創建線程時,會為其分配獨立的棧區空間(默認8M)。線程和所在的進程,以及進程中的其他線程,共用進程的堆區、文本區、數據區
線程的調度
????????宏觀并行,微觀串行
進程和線程的區別
進程 | 線程 | |
單位 | 操作系統資源分配的最小單位 | 操作系統任務調度的最小單位 |
資源消耗 | 資源消耗開銷大,每次創建都需要有0-4G的虛擬內存空間 | 資源消耗開銷較小,只需要由所在進程為其開辟默認8M的棧區空間 |
效率 | 由操作系統創建,創建耗時大,跨進程調度慢 | 由進程創建,創建耗時小,跨線程調度快 |
通信 | 進程間不能直接通信,需要使用進程間通信機制(IPC) | 通信簡單,可以使用線程共享的區域通信(例如全局變量) |
安全性 | 安全性較高,因為各個進程空間獨立 | 安全性較低,一個線程異常,可能影響同一進程中的線程 |
線程相關編程
? ? ? ? 線程的創建:pthread_read();pthread_self():獲取當前線程的ID號
? ? ? ? 線程的調度:由操作系統調度
? ? ? ? 線程的凋亡:
? ? ? ? ? ? ? ? 1,線程退出:在線程任務函數中使用return結束線程或者調用pthread_exit()結束線程
? ? ? ? ? ? ? ? 2,線程回收:pthread_join(tid,NULL)
pthread_create()
? ? ? ? 功能:創建一個新的線程
? ? ? ? 參數:
? ? ? ? ? ? ? ? thread:保存線程ID的變量地址
? ? ? ? ? ? ? ? attr:線程屬性的對象地址,如果是NULL則按照默認屬性創建
? ? ? ? ? ? ? ? void *(*start_routine)(void *):函數指針,指向線程啟動后要執行的任務
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 指針名稱:start_routine
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 指向的對象:函數void *()(void *)
? ? ? ? ? ? ? ? arg:為線程任務函數傳遞的參數,如果不傳參則傳NULL
? ? ? ? 返回值:成功則為0,失敗則為!0
? ? ? ? 需要注意的是,在使用這個函數時,需要在創建或者編譯時加上后綴,如圖所示
? ? ? ? 當進程中創建了線程,不要直接退出進程(線程之后就接return),在return之前設立一個死循環或者sleep,否則可能線程還未執行,進程就優先結束,連帶著線程也結束
pthread_exit()
? ? ? ? 功能:退出一個線程任務
? ? ? ? 參數:向回收的線程傳遞的參數的地址,如果不傳遞參數則為NULL
? ? ? ? pthread_exit(NULL)等價于return NULL
pthread_join()
? ? ? ? 功能:阻塞等待回收線程資源空間
? ? ? ? 參數:要回收的線程ID;用來保存線程退出時傳遞的參數,NULL表示不接收傳遞的參數
? ? ? ? 返回值:成功為0,失敗為-1
線程屬性
? ? ? ? 1,分離屬性:不需要被其他線程回收的線程,將來會被操作系統回收
? ? ? ? 2,非分離屬性:可以被其他線程回收或者結束的線程,默認屬性為非分離屬性
線程回收策略
? ? ? ? 1,分離屬性的線程:不需要回收(沒有空閑的線程可以幫忙回收)
? ? ? ? 2,調用pthread_join阻塞回收
int pthread_detach(pthread_t thread)
? ? ? ? 功能:將線程設置成分離屬性的線程
線程間通信
? ? ? ? 臨界資源:多個線程可以同時訪問的資源,例如全局變量,共享內存區域
? ? ? ? 然而,在多個線程在訪問臨界資源時,會存在資源競爭問題,如下
? ? ? ? 如果按照代碼正常思路,最后輸出應該是200000,但是最后卻輸出199997,這是由于對于全局變量n,其中一個線程調用并進行操作,還未將結果重新賦予時,另一個線程也進行了調用,導致兩個線程賦予了同一個值。
????????事實上,數字越大越容易出現這種情況,但是并不代表每次運行都會出現這種情況,所以為了完全避免這種資源競爭問題,需要用到互斥機制
互斥機制
? ? ? ? 互斥機制:多個線程訪問臨界資源時,具有排他性訪問的機制,即一次只允許一個線程對該臨界資源進行訪問
? ? ? ? 實現互斥機制的步驟
? ? ? ? ? ? ? ? 1,創建互斥鎖:pthread_mutex_t
? ? ? ? ? ? ? ? 2,初始化互斥鎖:pthread_mutex_init
? ? ? ? ? ? ? ? 3,鎖上:int pthread_mutex_lock(pthread_mutex_t *mutex)
? ? ? ? ? ? ? ? 4,解鎖:int pthread_mutex_unlock(pthread_mutex_t *mutex)
? ? ? ? ? ? ? ? 5,銷毀鎖:int pthread_mutex_destroy(pthread_mutex_t *mutex)
pthread_mutex_init
? ? ? ? 功能:初始化互斥鎖
? ? ? ? 參數:鎖住對象的地址;鎖的屬性,如果是NULL則為默認屬性
? ? ? ? 返回值:成功則為0,失敗則為-1
? ? ? ? 所以上述的例子可改為