新聞中心
Linux 多線程編程是一種復(fù)雜的編程方式,它與傳統(tǒng)的單線程編程方式有著明顯的不同。在多線程編程中,一個程序可以同時執(zhí)行多個任務(wù),這些任務(wù)可以在一個或者多個進程間進行切換。但是,多線程編程也面臨著許多挑戰(zhàn),比如全局變量數(shù)據(jù)共享問題。

創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比靖西網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式靖西網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋靖西地區(qū)。費用合理售后完善,10余年實體公司更值得信賴。
在本文中,我們將探討在 Linux 多線程編程中的全局變量問題,包括定義全局變量、全局變量的作用域以及如何合理使用全局變量。
定義全局變量
在多線程編程中,我們通常需要在不同的線程享數(shù)據(jù)。全局變量是一種最常用的共享數(shù)據(jù)路徑,因為它可以被所有進程訪問。在 Linux 中,我們可以通過將變量定義在文件的頭文件中來定義全局變量。
例如:
“`c
int global_var;
“`
在這個例子中,我們定義了一個名為 global_var 的整型變量作為全局變量。在多個線程之間,可以通過訪問這個全局變量來共享數(shù)據(jù)。
全局變量的作用域
在使用全局變量時需要注意作用域的問題。
在程序中,有不同的作用域范圍,從而影響了變量的可見性。在多線程編程中,我們需要將全局變量的作用域限定在各個線程中,以避免線程之間的競爭問題。
比如,我們可以在不同的函數(shù)中定義同名的全局變量。這些變量之間是沒有任何影響的,因為它們的作用域范圍不同。
例如,我們在 file1.c 中定義了一個全局變量:
“`c
int num1 = 10;
“`
在另一個文件 file2.c 中,我們定義了一個同名的全局變量:
“`c
int num1 = 20;
“`
在這種情況下,num1 可以分別被 file1.c 和 file2.c 中的代碼訪問,但它們之間沒有任何關(guān)系。
在多線程編程中,我們可以通過將全局變量定義為靜態(tài),來限制其作用域只在一個線程中。
例如:
“`c
static int global_var;
“`
這個定義告訴編譯器,全局變量 global_var 只能在當(dāng)前文件的作用域范圍內(nèi)使用。這可以避免在多個線程之間出現(xiàn)全局變量的競爭問題。
合理使用全局變量
全局變量雖然方便,但在多線程編程中,使用全局變量也有可能引起競爭問題。在多個線程同時修改一個全局變量時,有可能導(dǎo)致數(shù)據(jù)錯亂或者程序崩潰。
因此,在多線程編程中,我們需要合理地使用全局變量,盡可能避免在不同線程中修改同一個全局變量。一些常用的方法包括:
1. 在不同線程之間傳遞變量通過參數(shù)傳遞的方式,而不是使用全局變量。
2. 如果必須使用全局變量,需要使用加鎖技術(shù)來保護全局變量的訪問。只有在一個線程獲取到了鎖的情況下,才能修改這個全局變量。
3. 在編寫程序時,應(yīng)當(dāng)盡可能地避免使用全局變量,采用局部變量來代替。
結(jié)論
在 Linux 多線程編程中,全局變量的問題是需要注意的。全局變量可以方便地共享數(shù)據(jù),但同時也需要注意變量的作用域和安全性。我們需要在編寫程序時,根據(jù)實際情況合理地使用全局變量,盡可能地避免出現(xiàn)競爭問題。
相關(guān)問題拓展閱讀:
- 如何使用 linux下多線程中條件變量
如何使用 linux下多線程中條件變量
使用條件變量更大的好處是可以避免忙等。相當(dāng)與多線程中的信號。
條件變量是線程中的東西就是等待某一條件的發(fā)生和信號一樣
以下是說明
,條件變量使我們可以睡眠等待某種條件出現(xiàn)。
條件變量是利用線程間共享的全局變量進行同步的一種機制,主要包括兩個動作:一個線程等待”條件變量的條件成立”而掛起;另一個線程使”條件成立”(給出條件成立信號)。為了防止槐凳競爭,條件變量的使用總是和一個互斥鎖結(jié)合在一起。
條件變量類型為pthread_cond_t
創(chuàng)建和注銷
條件變量和互斥鎖一樣,都有靜態(tài)動態(tài)兩種創(chuàng)建方式,靜態(tài)方式使用PTHREAD_COND_INITIALIZER常量,如下:
pthread_cond_t
cond=PTHREAD_COND_INITIALIZER
動態(tài)方式調(diào)用pthread_cond_init()函數(shù),API定義如下:
int
pthread_cond_init(pthread_cond_t
*cond,
pthread_condattr_t
*cond_attr)
盡管POSIX標(biāo)準(zhǔn)中為條件變量定義了屬性,但在LinuxThreads中沒有實現(xiàn),因此cond_attr值通常為NULL,且被忽略。
注銷一個條件變量需要調(diào)用pthread_cond_destroy(),只有在沒有線程在該條件變量上等待的時候才能注銷這個條件變量,否則返回EBUSY。API定義如下:
int
pthread_cond_destroy(pthread_cond_t
*cond)
等待和激發(fā)
int
pthread_cond_wait(pthread_cond_t
*cond,
pthread_mutex_t
*mutex)
int
pthread_cond_timedwait(pthread_cond_t
*cond,
pthread_mutex_t
*mutex,
const
struct
timespec
*abstime)
等待條件有兩種方式:無條件等待pthread_cond_wait()和計時等待pthread_cond_timedwait(),其中計時等待方式如果在給定時刻前條件沒有滿足,則返回ETIMEOUT,結(jié)束等待,其中abstime以與time()系統(tǒng)調(diào)用相同意義的絕對時間形式出現(xiàn),0表示格林尼治時間1970年1月1日0時0分0秒。
使用絕對時間而非相對時間的優(yōu)點是吵明。如果函數(shù)提前返回(很可能因為捕獲了一個信號,)
無論哪種等待方式,都必須和一個互斥鎖配合,以防止多個線程同時請求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的競爭條件(Race
Condition)。mutex互斥鎖必須是普通鎖(PTHREAD_MUTEX_TIMED_NP)或者適應(yīng)鎖(PTHREAD_MUTEX_ADAPTIVE_NP),且在調(diào)用pthread_cond_wait()前必須由本線程加鎖(pthread_mutex_lock()),而在更新條件等待隊列以前,mutex保持鎖定狀態(tài),并在線程掛起進入等待前解鎖。在條件滿足從而離開pthread_cond_wait()之前,mutex將被重新加鎖,以與進入pthread_cond_wait()前的加鎖動作對應(yīng)。
激發(fā)條件有兩種形式,pthread_cond_signal()激活鉛碰旅一個等待該條件的線程,存在多個等待線程時按入隊順序激活其中一個;而pthread_cond_broadcast()則激活所有等待線程。
其他
pthread_cond_wait()和pthread_cond_timedwait()都被實現(xiàn)為取消點,因此,在該處等待的線程將立即重新運行,在重新鎖定mutex后離開pthread_cond_wait(),然后執(zhí)行取消動作。也就是說如果pthread_cond_wait()被取消,mutex是保持鎖定狀態(tài)的,因而需要定義退出回調(diào)函數(shù)來為其解鎖。
在網(wǎng)上看到這個系列的
文章對Linux下的POSIX線程編程方法闡述的十分的清晰,小弟目前關(guān)心要學(xué)習(xí)線程同步中的條件變量的使用方法,轉(zhuǎn)載一下呵呵……
互斥對象是線程程序必需的工具,但它們并非萬能的。例如,如果線程正在侍者等待共享數(shù)據(jù)內(nèi)某個條件出現(xiàn),那會發(fā)生什么呢?代碼可以反復(fù)對互斥對象鎖定和解鎖, 以檢查值的任何變化。同時,還要快速將互斥對象解鎖,以便其它線程能夠進行任何必需的更改。這是一種非??膳碌姆椒ǎ驗榫€程需要在合理的時間范圍內(nèi)頻繁 地循環(huán)檢測變化。
在每次檢查之間,可以讓調(diào)用線程短暫地進入睡眠,比如睡眠三秒鐘,但是因此線程代碼就無法最快作出響應(yīng)。真正需要的是這樣一種方法,當(dāng)線程在等待滿足某些 條件時使線程進入睡眠狀態(tài)。一旦條件滿足,還需要一種方法以喚醒因等待滿足特定條件而睡眠的線程。如果能夠做到這一點,線程代碼將是非常高效的,并且不會 占用寶貴的互斥對象鎖。這正是 POSIX 條件變量能做的事!
本文是 POSIX 線程三部曲系列的最后一部分,Daniel 將詳細(xì)討論如何使用條件變量。條件變量是 POSIX 線程結(jié)構(gòu),可以讓您在遇到某些條件時“喚醒”線程??梢詫⑺鼈兛醋魇且环N線程安全的信號發(fā)送。Daniel 使用目前您所學(xué)到的知識實現(xiàn)了一個多線程工作組應(yīng)用程序,本文將圍繞著這一示例而進行討論。
條件變量詳解
在 上一篇文章結(jié) 束時,我描述了一個比較特殊的難題:如果線程正在等待某個特定條件發(fā)生,它應(yīng)該如何處理這種情況?它可以重復(fù)對互斥對象鎖定和解鎖,每次都會檢查共享數(shù)據(jù) 結(jié)構(gòu),以查找某個值。但這是在浪費時間和資源,而且這種繁忙查詢的效率非常低。解決這個問題的更佳方法是使用 pthread_cond_wait() 調(diào)用來等待特殊條件發(fā)生。
了解 pthread_cond_wait() 的作用非常重要 — 它是 POSIX 線程信號發(fā)送系統(tǒng)的核心,也是最難以理解的部分。
首先,讓我們考慮以下情況:線程為查看已鏈接列表而鎖定了互斥對象,然而該列表恰巧是空的。這一特定線程什么也干不了 — 其設(shè)計意圖是從列表中除去節(jié)點,但是現(xiàn)在卻沒有節(jié)點。因此,它只能:
鎖定互斥對象時,線程將調(diào)用 pthread_cond_wait(&mycond,&mymutex)。pthread_cond_wait() 調(diào)用相當(dāng)復(fù)雜,因此我們每次只執(zhí)行它的一個操作。
pthread_cond_wait() 所做的之一件事就是同時對互斥對象解鎖(于是其它線程可以修改已鏈接列表),并等待條件 mycond 發(fā)生(這樣當(dāng) pthread_cond_wait() 接收到另一個線程的氏襪“信號”時,它將蘇醒)?,F(xiàn)在互斥對象已被解鎖,其它線程可以訪問和修改已鏈接列表,可能還會添加項。
此 時,pthread_cond_wait() 調(diào)用還未返回。對互斥對象解鎖會立即發(fā)生,但等待條件 mycond 通常是一個阻塞操作,這意味著線程將睡眠,在它蘇醒之前不會消耗 CPU 周期。這正是我們期待發(fā)生的情況。線程將一直睡眠,直到特定條件發(fā)生,在這期間不會發(fā)生任何浪費 CPU 時間的繁忙查詢。從線程的角度來看,它只是在等待 pthread_cond_wait() 調(diào)用返回。
現(xiàn)在繼續(xù)說明,假設(shè) 另一個線程(稱作“2 號線程”)鎖定了 mymutex 并對已鏈接列表添加了一項。在對互斥對象解鎖之后,2 號線程會立即調(diào)用函數(shù) pthread_cond_broadcast(&mycond)。此操作之后,2 號線程將使所有等待 mycond 條件變量的線程立即蘇醒。這意味著之一個線程(仍處于 pthread_cond_wait() 調(diào)用中)現(xiàn)在將蘇醒。
現(xiàn) 在,看一下之一個線程發(fā)生了什么。您可能會認(rèn)為在 2 號線殲談激程調(diào)用 pthread_cond_broadcast(&mymutex) 之后,1 號線程的 pthread_cond_wait() 會立即返回。不是那樣!實際上,pthread_cond_wait() 將執(zhí)行最后一個操作:重新鎖定 mymutex。一旦 pthread_cond_wait() 鎖定了互斥對象,那么它將返回并允許 1 號線程繼續(xù)執(zhí)行。那時,它可以馬上檢查列表,查看它所感興趣的更改。
關(guān)于linux多線程 全局變量的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
成都創(chuàng)新互聯(lián)科技有限公司,是一家專注于互聯(lián)網(wǎng)、IDC服務(wù)、應(yīng)用軟件開發(fā)、網(wǎng)站建設(shè)推廣的公司,為客戶提供互聯(lián)網(wǎng)基礎(chǔ)服務(wù)!
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡單好用,價格厚道的香港/美國云服務(wù)器和獨立服務(wù)器。創(chuàng)新互聯(lián)成都老牌IDC服務(wù)商,專注四川成都IDC機房服務(wù)器托管/機柜租用。為您精選優(yōu)質(zhì)idc數(shù)據(jù)中心機房租用、服務(wù)器托管、機柜租賃、大帶寬租用,可選線路電信、移動、聯(lián)通等。
文章標(biāo)題:深入理解Linux多線程編程中的全局變量問題(linux多線程全局變量)
當(dāng)前路徑:http://www.fisionsoft.com.cn/article/copghpj.html


咨詢
建站咨詢
