日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

【linux】多线程编程(c语言编程)

發(fā)布時間:2025/6/15 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【linux】多线程编程(c语言编程) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

多線程編程

一、線程的基本概念
?? ??? ?與進程相比,多線程是一種非常“節(jié)儉”的多任務操作方式。在linux操作系統(tǒng)下,啟動一個新進程必須給
?? ?它分配獨立的地址空間,建立眾多的數(shù)據(jù)表來維護它的代碼段、堆棧段和數(shù)據(jù)段,這是一種“昂貴”的多任務
?? ?工作方式;而運行一個進程中的多個線程,它們彼此之間使用相同的地址空間,共享大部分數(shù)據(jù),啟動一個
?? ?線程所花費的空間遠遠小于啟動一個進程所花費的空間,線程間彼此切換所需的時間也遠遠少于進程間切換
?? ?所需要的時間。
?? ??? ?進程作為獨立的實體,它為線程提供運行的資源并構成靜態(tài)環(huán)境。線程是處理機調(diào)度的基本單位。如果
?? ?說進程概念很好的描述了單機操作系統(tǒng)行為,那么線程概念則很好的描述了多機系統(tǒng)的并行處理行為。?? ?
?? ??? ?多線程工作方式提供了線程間方便的通信機制。由于同一進程下的線程之間共享數(shù)據(jù)空間,所以一個線
?? ?程的數(shù)據(jù)可以直接為其它線程使用,這不僅快捷,而且方便。
?? ??? ?多線程程序還有以下優(yōu)點:提高應用程序響應,使CPU系統(tǒng)更加有效,改善程序結(jié)構。
?? ??? ?
二、線程的實現(xiàn)
?? ??? ?linux系統(tǒng)下的多線程遵循POSIX線程接口,稱為PTHREAD。編寫linux下的多線程程序,需要使用頭文件
?? ?pthread.h,連接時需要使用庫文件libpthread.a.(因此編譯時需要添加選項:-lpthread)
?? ?
?? ?(1)創(chuàng)建線程:即確定調(diào)用該線程函數(shù)的入口點,通常使用的函數(shù)是pthread_create。
?? ?
?? ? 函數(shù)原型:

????????int?pthread(pthread_t?*?thread,?pthread_attr_t?*?attr,?void?*?(?*?start_routine)?(void?*),?void?arg));pthread:?線程標識符attr:?線程屬性start_routine:線程運行函數(shù)的起始地址(線程函數(shù)名)arg:運行函數(shù)的參數(shù)(線程函數(shù)所需的參數(shù))返回值:創(chuàng)建成功——返回0,若不為0則為創(chuàng)建線程失敗(EAGAIN,EINVAL)

?? ?(2)線程掛起
?? ??? ??? ?一個進程中的多個線程是共享數(shù)據(jù)段的,因此通常在線程退出后,退出線程所占用的資源并不會隨
?? ??? ?著線程的終止而釋放。就如進程中的wait(),線程之間使用pthread_join()函數(shù)將當前線程掛起,等待
?? ??? ?線程的結(jié)束。pthread_join()是一個線程阻塞的函數(shù),調(diào)用它的函數(shù)將一直等待到被等待線程的結(jié)束。
?? ??? ??? ?需要注意的是,一個線程不能被多個線程等待,否則第一個接收到信號的線程成功返回,其余的將
?? ??? ?返回錯誤代碼。
?? ??? ?
?? ??? ?函數(shù)原型:

????????????int?pthread_join(pthread_t?th,?void?**?thread_return);th:?被等待的線程標識符thread_return:用戶定義的指針,用于存儲被等待線程的返回值

?? ??? ??? ??? ?
?? ?(3)線程的結(jié)束:1、相關線程函數(shù)運行結(jié)束;2、調(diào)用pthread_exit()函數(shù)
?? ?
?? ??? ?函數(shù)原型:

????????????void?pthread_exit(void?*?retval)retval:函數(shù)的返回代碼,即thread_return

?? ??? ??? ?
?? ??? ?示例:

????????????void?thread(void){}//線程運行函數(shù)pthread_t?id;pthread(&id,NULL,(void?*)thread,NULL);//創(chuàng)建線程,第一個NULL?——?生成默認屬性的線程,第二個NULL?——?線程運行函數(shù)不需要參數(shù)pthread_join(id,NULL);//掛起線程

?? ??? ?
三、修改線程屬性
?? ??? ?線程屬性值不能直接設置,需要調(diào)用相關的函數(shù)進行操作,初始化的函數(shù)為pthread_attr_init,這個函
?? ?數(shù)必須在pthread_create函數(shù)之前調(diào)用。屬性對象包括是否綁定、是否分離、堆棧地址、堆棧大小和優(yōu)先級。
?? ?默認的屬性為非綁定、非分離、缺省1MB的堆棧和與父進程同樣級別的優(yōu)先級。對于大多數(shù)程序來說,使用默
?? ?認屬性就夠了。
?? ?
?? ?1、綁定
?? ??? ?關于綁定涉及到另一個概念:輕進程LWP(Light Weight Process)。可理解為內(nèi)核線程,系統(tǒng)對線程
?? ?資源的分配和對線程的控制是通過輕進程來實現(xiàn)的。默認情況下,由系統(tǒng)來控制啟動多少輕進程、哪些輕進
?? ?程控制哪些線程,這種狀態(tài)稱為非綁定的。綁定即某個線程固定的“綁”在一個輕線程上。被綁定的線程具
?? ?有較高的反應速度(CPU時間片的調(diào)度是面向輕進程的)。
?? ??? ?通過設置被綁定的輕進程的優(yōu)先級和調(diào)度級可以使得綁定的線程滿足實時反應之類的要求
?? ??? ?
?? ?創(chuàng)建一個綁定的線程:(pthread_attr_setscope)

????????pthread_attr_t?attr;pthread_t?tid;pthread_attr_init(&attr);//初始化屬性值,均設為默認值pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);//設置綁定狀態(tài)pthread_create(&id,?&attr,?(void?*)?my_function,?NULL);attr:?指向?qū)傩越Y(jié)構的指針綁定類型:PTHREAD_SCOPE_SYSTEM(綁定的),PTHREAD_SCOPE_PROCESS(非綁定的)

?? ??? ??? ?
?? ?2、分離
?? ??? ?線程的分離狀態(tài)決定一個線程以什么樣的方式來終止自己。
?? ??? ??? ?非分離:原有的線程等待創(chuàng)建的線程結(jié)束,只有pthread_join()函數(shù)返回時才釋放所占資源。
?? ??? ??? ?分離:不被其他進程所等待,運行結(jié)束后馬上釋放所占資源。
?? ??? ??? ?
?? ??? ?線程分離狀態(tài)的函數(shù):

????????????pthread_attr_setdetachstate(pthread_attr_t?*?attr,?int?detachstate)detachstate:?PTHREAD_CREATE_DETACHED(分離線程),?PTHREAD_CREATE_JOINABLE(非分離線程)

?? ??? ??? ?
?? ??? ??? ??? ?如果設置了一個線程為分離線程,而這個線程運行又非常快,它很可能在pthread_create函數(shù)
?? ??? ??? ?返回之前就終止了,這樣調(diào)用pthread_create的線程就可能得到錯誤的線程號。為避免這種情況,
?? ??? ??? ?通常在創(chuàng)建的線程里調(diào)用pthread_cond_timewait函數(shù),讓這個線程等待會兒。
?? ??? ??? ?
?? ?3、優(yōu)先級
?? ??? ?優(yōu)先級存放在結(jié)構sched_param中,用函數(shù)pthread_attr_getschedparam和pthread_attr_setschedparam
?? ?進行存放。一般而言是先取優(yōu)先級,然后對優(yōu)先級進行修改后再存放回去。
?? ?
?? ?例如:

????????pthread_attr_t?attr;//屬性pthread_t?tid;//線程標識符sched_param?param;//優(yōu)先級int?newprio?=?20;//新的優(yōu)先級pthread_attr_init(&attr);pthread_attr_getschedparam(&attr,&param);/取出優(yōu)先級param.sched_priority?=?newprio;//修改優(yōu)先級pthread_attr_setschedparam(&attr,&param);//寫回優(yōu)先級pthread_create(&tid,?&attr,?(void?*)myfunction,?NULL);

?? ??? ??? ?
四、多線程訪問控制
?? ??? ?由于多線程共享進程的資源和地址空間,因此對這些資源進行操作時,必須考慮到線程間資源訪問的唯
?? ?一性問題。
?? ??? ?互斥鎖有一個明顯的缺點:只有兩種狀態(tài)(鎖定和非鎖定),而條件變量通過允許線程阻塞和等待另一個線
?? ?程發(fā)送信號的方法彌補了互斥鎖的不足,它常和互斥鎖一起使用。

?? ?1、pthread_cond_init ()函數(shù) —— 用于初始化一個條件變量
?? ??? ?int pthread_cond_init(pthread_cond_t * cond, __const pthread_condattr_t * cond_attr)
?? ??? ?
?? ??? ?cond: 指向結(jié)構pthread_cond_t的指針
?? ??? ?cond_attr: 條件變量的屬性結(jié)構(默認值——PTHREAD_PROCESS_PRIVATE)
?? ??? ?
?? ??? ?初始化條件變量只有未被使用時才能重新初始化或被釋放。
?? ??? ?釋放條件變量的函數(shù):pthread_cond_destroy(pthread_cond_t cond)
?? ??? ?
?? ?2、pthread_cond_wait()函數(shù) —— 使線程阻塞在一個條件變量上
?? ??? ?extern int pthread_cond_wait(pthread_cond_t * __restrict__cond,
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?pthread_mutex_t * __restrict__mutex)
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ?線程解開mutex指向的鎖并被條件變量cond阻塞。
?? ??? ?
?? ?3、pthread_cond_timedwait()函數(shù) —— 用于阻塞線程的另一個函數(shù)
?? ??? ?extern int pthread_cond_timedwait __P((pthread_cond_t * __restrict__cond,
?? ??? ??? ??? ??? ?pthread_mutex_t * __restrict__mutex, __const struct timespec * __abstime))
?? ??? ??? ?
?? ??? ?它比thread_cond_wait()函數(shù)多了一個時間參數(shù),經(jīng)歷abstime時間后,即使條件變量不滿足,
?? ??? ?阻塞也被解除。
?? ??? ?
?? ?4、pthread_cond_signal()函數(shù) —— 用來釋放被阻塞在條件變量cond上的一個線程。
?? ??? ?extern int pthread_cond_signal(pthread_cond_t * __cond)

?? ??? ?需要注意的是,必須用保護條件變量的互斥鎖來保護這個函數(shù),否則條件滿足信號又可能在測試條件和
?? ??? ?調(diào)用pthread_cond_wait()函數(shù)之間被發(fā)出,從而造成無限制的等待。
?? ??? ?
?? ?5、其它常用線程函數(shù)
?? ??? ?獲得父進程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)
?? ??? ??? ??? ?
?? ??? ??? ??? ?
?? ??? ??? ??? ?
?? ??? ??? ????

轉(zhuǎn)載于:https://blog.51cto.com/tobeys/1720019

總結(jié)

以上是生活随笔為你收集整理的【linux】多线程编程(c语言编程)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。