天天看點

【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)

繼續閱讀