【linux】多线程编程(c语言编程)
多線程編程
一、線程的基本概念
?? ??? ?與進程相比,多線程是一種非常“節儉”的多任務操作方式。在linux操作系統下,啟動一個新進程必須給
?? ?它分配獨立的地址空間,建立眾多的數據表來維護它的代碼段、堆棧段和數據段,這是一種“昂貴”的多任務
?? ?工作方式;而運行一個進程中的多個線程,它們彼此之間使用相同的地址空間,共享大部分數據,啟動一個
?? ?線程所花費的空間遠遠小于啟動一個進程所花費的空間,線程間彼此切換所需的時間也遠遠少于進程間切換
?? ?所需要的時間。
?? ??? ?進程作為獨立的實體,它為線程提供運行的資源并構成靜態環境。線程是處理機調度的基本單位。如果
?? ?說進程概念很好的描述了單機操作系統行為,那么線程概念則很好的描述了多機系統的并行處理行為。?? ?
?? ??? ?多線程工作方式提供了線程間方便的通信機制。由于同一進程下的線程之間共享數據空間,所以一個線
?? ?程的數據可以直接為其它線程使用,這不僅快捷,而且方便。
?? ??? ?多線程程序還有以下優點:提高應用程序響應,使CPU系統更加有效,改善程序結構。
?? ??? ?
二、線程的實現
?? ??? ?linux系統下的多線程遵循POSIX線程接口,稱為PTHREAD。編寫linux下的多線程程序,需要使用頭文件
?? ?pthread.h,連接時需要使用庫文件libpthread.a.(因此編譯時需要添加選項:-lpthread)
?? ?
?? ?(1)創建線程:即確定調用該線程函數的入口點,通常使用的函數是pthread_create。
?? ?
?? ? 函數原型:
?? ?(2)線程掛起
?? ??? ??? ?一個進程中的多個線程是共享數據段的,因此通常在線程退出后,退出線程所占用的資源并不會隨
?? ??? ?著線程的終止而釋放。就如進程中的wait(),線程之間使用pthread_join()函數將當前線程掛起,等待
?? ??? ?線程的結束。pthread_join()是一個線程阻塞的函數,調用它的函數將一直等待到被等待線程的結束。
?? ??? ??? ?需要注意的是,一個線程不能被多個線程等待,否則第一個接收到信號的線程成功返回,其余的將
?? ??? ?返回錯誤代碼。
?? ??? ?
?? ??? ?函數原型:
?? ??? ??? ??? ?
?? ?(3)線程的結束:1、相關線程函數運行結束;2、調用pthread_exit()函數
?? ?
?? ??? ?函數原型:
?? ??? ??? ?
?? ??? ?示例:
?? ??? ?
三、修改線程屬性
?? ??? ?線程屬性值不能直接設置,需要調用相關的函數進行操作,初始化的函數為pthread_attr_init,這個函
?? ?數必須在pthread_create函數之前調用。屬性對象包括是否綁定、是否分離、堆棧地址、堆棧大小和優先級。
?? ?默認的屬性為非綁定、非分離、缺省1MB的堆棧和與父進程同樣級別的優先級。對于大多數程序來說,使用默
?? ?認屬性就夠了。
?? ?
?? ?1、綁定
?? ??? ?關于綁定涉及到另一個概念:輕進程LWP(Light Weight Process)。可理解為內核線程,系統對線程
?? ?資源的分配和對線程的控制是通過輕進程來實現的。默認情況下,由系統來控制啟動多少輕進程、哪些輕進
?? ?程控制哪些線程,這種狀態稱為非綁定的。綁定即某個線程固定的“綁”在一個輕線程上。被綁定的線程具
?? ?有較高的反應速度(CPU時間片的調度是面向輕進程的)。
?? ??? ?通過設置被綁定的輕進程的優先級和調度級可以使得綁定的線程滿足實時反應之類的要求
?? ??? ?
?? ?創建一個綁定的線程:(pthread_attr_setscope)
?? ??? ??? ?
?? ?2、分離
?? ??? ?線程的分離狀態決定一個線程以什么樣的方式來終止自己。
?? ??? ??? ?非分離:原有的線程等待創建的線程結束,只有pthread_join()函數返回時才釋放所占資源。
?? ??? ??? ?分離:不被其他進程所等待,運行結束后馬上釋放所占資源。
?? ??? ??? ?
?? ??? ?線程分離狀態的函數:
?? ??? ??? ?
?? ??? ??? ??? ?如果設置了一個線程為分離線程,而這個線程運行又非常快,它很可能在pthread_create函數
?? ??? ??? ?返回之前就終止了,這樣調用pthread_create的線程就可能得到錯誤的線程號。為避免這種情況,
?? ??? ??? ?通常在創建的線程里調用pthread_cond_timewait函數,讓這個線程等待會兒。
?? ??? ??? ?
?? ?3、優先級
?? ??? ?優先級存放在結構sched_param中,用函數pthread_attr_getschedparam和pthread_attr_setschedparam
?? ?進行存放。一般而言是先取優先級,然后對優先級進行修改后再存放回去。
?? ?
?? ?例如:
?? ??? ??? ?
四、多線程訪問控制
?? ??? ?由于多線程共享進程的資源和地址空間,因此對這些資源進行操作時,必須考慮到線程間資源訪問的唯
?? ?一性問題。
?? ??? ?互斥鎖有一個明顯的缺點:只有兩種狀態(鎖定和非鎖定),而條件變量通過允許線程阻塞和等待另一個線
?? ?程發送信號的方法彌補了互斥鎖的不足,它常和互斥鎖一起使用。
?? ?1、pthread_cond_init ()函數 —— 用于初始化一個條件變量
?? ??? ?int pthread_cond_init(pthread_cond_t * cond, __const pthread_condattr_t * cond_attr)
?? ??? ?
?? ??? ?cond: 指向結構pthread_cond_t的指針
?? ??? ?cond_attr: 條件變量的屬性結構(默認值——PTHREAD_PROCESS_PRIVATE)
?? ??? ?
?? ??? ?初始化條件變量只有未被使用時才能重新初始化或被釋放。
?? ??? ?釋放條件變量的函數:pthread_cond_destroy(pthread_cond_t cond)
?? ??? ?
?? ?2、pthread_cond_wait()函數 —— 使線程阻塞在一個條件變量上
?? ??? ?extern int pthread_cond_wait(pthread_cond_t * __restrict__cond,
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?pthread_mutex_t * __restrict__mutex)
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ?線程解開mutex指向的鎖并被條件變量cond阻塞。
?? ??? ?
?? ?3、pthread_cond_timedwait()函數 —— 用于阻塞線程的另一個函數
?? ??? ?extern int pthread_cond_timedwait __P((pthread_cond_t * __restrict__cond,
?? ??? ??? ??? ??? ?pthread_mutex_t * __restrict__mutex, __const struct timespec * __abstime))
?? ??? ??? ?
?? ??? ?它比thread_cond_wait()函數多了一個時間參數,經歷abstime時間后,即使條件變量不滿足,
?? ??? ?阻塞也被解除。
?? ??? ?
?? ?4、pthread_cond_signal()函數 —— 用來釋放被阻塞在條件變量cond上的一個線程。
?? ??? ?extern int pthread_cond_signal(pthread_cond_t * __cond)
?? ??? ?需要注意的是,必須用保護條件變量的互斥鎖來保護這個函數,否則條件滿足信號又可能在測試條件和
?? ??? ?調用pthread_cond_wait()函數之間被發出,從而造成無限制的等待。
?? ??? ?
?? ?5、其它常用線程函數
?? ??? ?獲得父進程ID:
?? ??? ??? ?pthread pthread_self(void)
?? ??? ?測試兩個線程號是否相同:
?? ??? ??? ?int pthread_equal(pthread_t __thread, pthread_t __thread2)
?? ??? ?互斥量初始化:
?? ??? ??? ?int pthread_mutex_init(pthread_mutex_t * , __const pthread_mutexattr_t * )
?? ??? ?銷毀互斥量:
?? ??? ??? ?int pthread_mutex_destroy(pthread_mutex_t *__mutex)
?? ??? ?再試一次獲得對互斥鎖量的鎖定(非阻塞)
?? ??? ??? ?int pthread_mutex_trylock(pthread_mutex_t *__mutex)
?? ??? ?鎖定互斥量(阻塞)
?? ??? ??? ?int pthread_mutex_lock(pthread_mutex_t *__mutex)
?? ??? ?解鎖互斥量
?? ??? ??? ?int pthead_mutex_unlock(pthread_mutex_t *__mutex)
?? ??? ?條件變量初始化
?? ??? ??? ?int pthread_cond_init(pthread_cond_t *__restrict__cond,
?? ??? ??? ??? ??? ??? ??? ??? ??? ?__const pthread_condattr_t *__restrict__cond_attr)
?? ??? ?銷毀條件變量cond
?? ??? ??? ?int pthread_cond_destroy(pthread_cond_t *__cond)
?? ??? ?喚醒線程等待條件變量
?? ??? ??? ?int pthread_cond_signal(pthread_cond_t *__cond)
?? ??? ?等待條件變量
?? ??? ??? ?int pthread_cond_wait(pthread_cond_t *__restrict__cond,
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?pthread_mutex_t * __restrict__mutex)
?? ??? ?在指定的時間到達前等待條件變量
?? ??? ??? ?int pthread_cond_timewait(pthread_cond_t *__restrict__cond,
?? ??? ??? ??? ?phread_mutex_t *__restrict__mutex, __const struct timespec *__restrict __abstime)
?? ??? ??? ??? ?
?? ??? ??? ??? ?
?? ??? ??? ??? ?
?? ??? ??? ????
轉載于:https://blog.51cto.com/tobeys/1720019
總結
以上是生活随笔為你收集整理的【linux】多线程编程(c语言编程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汉高澳大利亚sinox接口捆绑经典win
- 下一篇: 20135203齐岳 信息安全系统设计基