新聞中心
Linux 線程的共享內(nèi)存使用

虹口網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)從2013年開始到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
隨著計(jì)算機(jī)技術(shù)的不斷發(fā)展,多線程編程已經(jīng)成為了我們?nèi)粘i_發(fā)中的一個(gè)常見的技術(shù)。在多線程編程中,線程之間的數(shù)據(jù)的共享和通信也成為了關(guān)鍵的問題。而共享內(nèi)存就是解決線程之間數(shù)據(jù)共享和通信的一種方式。
Linux 內(nèi)核為多進(jìn)程和多線程提供了一種共享內(nèi)存的機(jī)制,使各個(gè)進(jìn)程和線程之間可以共享一片內(nèi)存區(qū)域,從而實(shí)現(xiàn)數(shù)據(jù)的共享和傳遞。在 Linux 中,共享內(nèi)存可以通過系統(tǒng)調(diào)用 shmget() 和 shmat() 來實(shí)現(xiàn)。shmat() 調(diào)用將共享內(nèi)存附加到調(diào)用進(jìn)程的地址空間中,而 shmget() 則負(fù)責(zé)分配共享內(nèi)存區(qū)域。
在使用 Linux 線程時(shí),共享內(nèi)存的使用也是非常常見的。線程之間共享內(nèi)存,可以提高程序的運(yùn)行效率,并且可以使多個(gè)線程協(xié)同工作,完成更加復(fù)雜的任務(wù)。下面來介紹一下 Linux 線程的共享內(nèi)存使用。
需要實(shí)現(xiàn)線程之間的共享內(nèi)存,需要開辟一塊共享內(nèi)存區(qū)域。這個(gè)共享內(nèi)存區(qū)域可以通過 shmget() 系統(tǒng)調(diào)用來實(shí)現(xiàn)。shmget() 調(diào)用需要指定共享內(nèi)存的大小、權(quán)限以及共享內(nèi)存的標(biāo)識(shí)符等參數(shù)。例如,下面的代碼演示了如何使用 shmget() 來創(chuàng)建一個(gè)共享內(nèi)存區(qū)域。
“`
#include
#include
#include
#include
#define SHMSZ 27
int mn()
{
int shmid;
key_t key;
char* shm, s;
key = 5678;
if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666))
{
perror(“shmget”);
exit(1);
}
if ((shm = shmat(shmid, NULL, 0)) == (char*)-1)
{
perror(“shmat”);
exit(1);
}
for (s = ‘a(chǎn)’; s
{
*shm++ = s;
}
*shm = 0;
return 0;
}
“`
上述代碼通過調(diào)用 shmget() 創(chuàng)建一個(gè)共享內(nèi)存區(qū)域,并且在程序中向共享內(nèi)存區(qū)寫入了一個(gè)小寫字母表。在使用共享內(nèi)存的過程中,需要注意內(nèi)存的大小以及內(nèi)存的權(quán)限問題。共享內(nèi)存的權(quán)限可以使用 chmod() 系統(tǒng)調(diào)用來設(shè)置,并且需要保證各個(gè)線程對(duì)共享內(nèi)存的訪問權(quán)限相同。
接下來,在 Linux 線程中使用共享內(nèi)存,需要使用 shmat() 系統(tǒng)調(diào)用將共享內(nèi)存附加到線程的地址空間中。下面的代碼演示了在 Linux 線程中使用共享內(nèi)存。
“`
#include
#include
#include
#include
#include
#define SHMSZ 27
void* thread_func(void* arg)
{
char* shm = (char*)arg;
while (*shm != 0)
{
putchar(*shm++);
}
putchar(‘\n’);
return NULL;
}
int mn()
{
int shmid;
key_t key;
char* shm;
pthread_t thread;
key = 5678;
if ((shmid = shmget(key, SHMSZ, 0666))
{
perror(“shmget”);
exit(1);
}
if ((shm = shmat(shmid, NULL, 0)) == (char*)-1)
{
perror(“shmat”);
exit(1);
}
pthread_create(&thread, NULL, thread_func, (void*)shm);
pthread_join(thread, NULL);
return 0;
}
“`
上述代碼創(chuàng)建了一個(gè) Linux 線程,并且將共享內(nèi)存附加到線程的地址空間中。線程使用了共享內(nèi)存來獲取數(shù)據(jù)并打印輸出。在使用共享內(nèi)存的過程中,需要注意幾個(gè)問題:首先需要保證共享內(nèi)存是按照約定的方式進(jìn)行使用,否則可能會(huì)引起不可預(yù)見的錯(cuò)誤;其次需要注意內(nèi)存空間的大小,以及內(nèi)存的讀寫操作的互斥問題;需要避免共享內(nèi)存的數(shù)據(jù)出現(xiàn)競爭的情況,從而保證數(shù)據(jù)的正確性和安全性。
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗(yàn)豐富以策略為先導(dǎo)10多年以來專注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),響應(yīng)式網(wǎng)站制作,設(shè)計(jì)師量身打造品牌風(fēng)格,熱線:028-86922220Linux C++多線程同步的四種方式
From :
1.同一個(gè)線程內(nèi)部,指令按照先后順序執(zhí)行;但不同線程之間的指令很難說清楚是哪一個(gè)先執(zhí)行,在并況下,指令執(zhí)行的先后順序由內(nèi)核決定。
如果運(yùn)行的結(jié)果依賴于不同線程執(zhí)行的先后的話,那么就會(huì)形成競爭條件,在這樣的情況下,計(jì)算的結(jié)果很難預(yù)知,所以應(yīng)該盡量避免競爭條件的形成。
2.最常見的解決競爭條件的方法是:將原先分離的兩個(gè)指令構(gòu)成一個(gè)不可分割的原子操作,而其他任務(wù)不能插入到原子操作中!
3.對(duì)
多線程
來說,同步指的是在一定時(shí)間內(nèi)只允許某一個(gè)線程訪問某個(gè)資源,而在此時(shí)間內(nèi),不允許其他線程訪問該資源!
互斥鎖
條件變量
讀寫鎖
信號(hào)量
一種特殊的
全局變量
,擁有l(wèi)ock和unlock兩種狀態(tài)。
unlock的互斥鎖可以由某個(gè)線程獲得,一旦獲得,這個(gè)互斥鎖會(huì)鎖上變成lock狀態(tài),此后只有該線程由權(quán)力打開該鎖,其他線程想要獲得互斥鎖,必須得到互斥鎖再次被打開之后。
1.互斥鎖的初始化, 分為靜態(tài)初始化和動(dòng)態(tài)初始化.
2.互斥鎖的相關(guān)屬性及分類
(1) attr表示互斥鎖的屬性;
(2) pshared表示互斥鎖的共享屬性,由兩種取值:
1)PTHREAD_PROCESS_PRIVATE:鎖只能用于一個(gè)進(jìn)程內(nèi)部的兩個(gè)線程進(jìn)行互斥(默認(rèn)情況)
2)PTHREAD_PROCESS_SHARED:鎖可用于兩個(gè)不同進(jìn)程中的線程進(jìn)行互斥,使用時(shí)還需要在進(jìn)程共享內(nèi)存中分配互斥鎖,然后為該互斥鎖指定屬性就可以了。
互斥鎖存在缺點(diǎn):
(1)某個(gè)線程正在等待共享數(shù)據(jù)內(nèi)某個(gè)條件出現(xiàn)。
(2)重復(fù)對(duì)數(shù)據(jù)對(duì)象加鎖和解鎖(輪詢),但是這樣輪詢非常耗費(fèi)時(shí)間和資源,而且效率非常低,所以互斥鎖不太適合這種情況。
當(dāng)線程在等待滿足某些條件時(shí),使線程進(jìn)入睡眠狀態(tài);一旦條件滿足,就換線因等待滿足特定條件而睡眠的線程。
程序的效率無疑會(huì)大大提高。
1)創(chuàng)建
靜態(tài)方式:pthread_cond_t cond PTHREAD_COND_INITIALIZER
動(dòng)態(tài)方式:int pthread_cond_init(&cond,NULL)
Linux thread 實(shí)現(xiàn)的條件變量不支持屬性,所以NULL(cond_attr參數(shù))
2)注銷
int pthread_cond_destory(&cond)
只有沒有線程在該條件變量上,該條件變量才能注饑畝銷,否則返回EBUSY
因?yàn)長inux實(shí)現(xiàn)的條件變量沒有分配什么資源,所以注銷動(dòng)作只包括檢查是否姿肢改有等待線程!(請(qǐng)參考條件變量的底層實(shí)現(xiàn))
3)等待
條件等待:int pthread_cond_wait(&cond,&mutex)
計(jì)時(shí)等待:int pthread_cond_timewait(&cond,&mutex,time)
1.其中計(jì)時(shí)等待如果在給定時(shí)刻前條件沒有被滿足,則返回ETIMEOUT,結(jié)束等待
2.無論那種等待方式,都必須有一個(gè)互斥鎖配合,以防止多個(gè)線程同時(shí)請(qǐng)求pthread_cond_wait形成競爭條件!
3.在調(diào)用pthread_cond_wait前必須由本線程加鎖
4)激發(fā)
激發(fā)一個(gè)等待線程:pthread_cond_signal(&cond)
激發(fā)所有等待線程:pthread_cond_broadcast(&cond)
重要的是,pthread_cond_signal不會(huì)存在驚群效應(yīng),也就是是它最多給一個(gè)等待線程發(fā)信號(hào),不會(huì)給所有線程發(fā)信號(hào)喚醒,然后要求他們自己去爭搶資源!
pthread_cond_broadcast() 喚醒所有正在pthread_cond_wait()的同一個(gè)條件變量的線程。注意:如果等待的多個(gè)現(xiàn)場不使用同一個(gè)鎖,被喚跡判醒的多個(gè)線程執(zhí)行是并發(fā)的。
pthread_cond_broadcast & pthread_cond_signal
1.讀寫鎖比互斥鎖更加具有適用性和并行性
2.讀寫鎖最適用于對(duì)
數(shù)據(jù)結(jié)構(gòu)
的讀操作讀操作次數(shù)多余寫操作次數(shù)的場合!
3.鎖處于讀模式時(shí)可以線程共享,而鎖處于寫模式時(shí)只能獨(dú)占,所以讀寫鎖又叫做共享-獨(dú)占鎖。
4.讀寫鎖有兩種策略:強(qiáng)讀同步和強(qiáng)寫同步
強(qiáng)讀同步:
總是給讀者更高的優(yōu)先權(quán),只要寫者沒有進(jìn)行寫操作,讀者就可以獲得訪問權(quán)限
強(qiáng)寫同步:
總是給寫者更高的優(yōu)先權(quán),讀者只能等到所有正在等待或者執(zhí)行的寫者完成后才能進(jìn)行讀
1)初始化的銷毀讀寫鎖
靜態(tài)初始化:pthread_rwlock_t rwlock=PTHREAD_RWLOCK_INITIALIZER
動(dòng)態(tài)初始化:int pthread_rwlock_init(rwlock,NULL),NULL代表讀寫鎖采用默認(rèn)屬性
銷毀讀寫鎖:int pthread_rwlock_destory(rwlock)
在釋放某個(gè)讀寫鎖的資源之前,需要先通過pthread_rwlock_destory函數(shù)對(duì)讀寫鎖進(jìn)行清理。釋放由pthread_rwlock_init函數(shù)分配的資源
如果你想要讀寫鎖使用非默認(rèn)屬性,則attr不能為NULL,得給attr賦值
int pthread_rwlockattr_init(attr),給attr初始化
int pthread_rwlockattr_destory(attr),銷毀attr
2)以寫的方式獲取鎖,以讀的方式獲取鎖,釋放讀寫鎖
int pthread_rwlock_rdlock(rwlock),以讀的方式獲取鎖
int pthread_rwlock_wrlock(rwlock),以寫的方式獲取鎖
int pthread_rwlock_unlock(rwlock),釋放鎖
上面兩個(gè)獲取鎖的方式都是阻塞的函數(shù),也就是說獲取不到鎖的話,調(diào)用線程不是立即返回,而是阻塞執(zhí)行,在需要進(jìn)行寫操作的時(shí)候,這種阻塞式獲取鎖的方式是非常不好的,你想一下,我需要進(jìn)行寫操作,不但沒有獲取到鎖,我還一直在這里等待,大大拖累效率
所以我們應(yīng)該采用非阻塞的方式獲取鎖:
int pthread_rwlock_tryrdlock(rwlock)
int pthread_rwlock_trywrlock(rwlock)
互斥鎖只允許一個(gè)線程進(jìn)入臨界區(qū),而信號(hào)量允許多個(gè)線程進(jìn)入臨界區(qū)。
1)信號(hào)量初始化
int sem_init(&sem,pshared, v)
pshared為0,表示這個(gè)信號(hào)量是當(dāng)前進(jìn)程的局部信號(hào)量。
pshared為1,表示這個(gè)信號(hào)量可以在多個(gè)進(jìn)程之間共享。
v為信號(hào)量的初始值。
返回值
:
成功:0,失?。?1
2)信號(hào)量值的加減
int sem_wait(&sem):以原子操作的方式將信號(hào)量的值減去1
int sem_post(&sem):以原子操作的方式將信號(hào)量的值加上1
3)對(duì)信號(hào)量進(jìn)行清理
int sem_destory(&sem)
麻煩解釋一下linux下進(jìn)程和線程有什么區(qū)別和聯(lián)系,linux下多線程和多進(jìn)程通信的實(shí)現(xiàn)方法,請(qǐng)通俗解釋
區(qū)別和聯(lián)系:
1、進(jìn)程是獨(dú)立運(yùn)行的實(shí)體,有獨(dú)立的資源分配;
2、同一進(jìn)程的線程之間共享進(jìn)程的資源;
3、所有的進(jìn)程至洞皮少有一個(gè)執(zhí)行線程;
4、納仔差線程的創(chuàng)建和切換代價(jià)比進(jìn)程的?。?/p>
線程間的通信方法:
1、同一進(jìn)程的線程之間通信戚喊的最簡單辦法就是使用全局變量;
2、不同進(jìn)程的線程之間通信需要通過下面進(jìn)程間的通信來實(shí)現(xiàn);
進(jìn)程間的通信方法:
1、管道
2、信號(hào)量
3、共享內(nèi)存
4、消息隊(duì)列
5、套接字
兄弟看到你這么高的分我就找了些資料:也算是對(duì)昨天學(xué)的知識(shí)總結(jié)一下吧
一、先說概念不管是windows還是linux下的進(jìn)程和線程概念都是一樣的,只是管理進(jìn)程和線程的方式不一樣,這個(gè)是前提,到時(shí)候你可別問我windows下進(jìn)程和線程啊。這個(gè)涉及到操作系統(tǒng)原理。下面給你解答。
說道進(jìn)程不得不提作業(yè)這個(gè)名詞 ,我想兄弟你電腦里不會(huì)有一個(gè)程序吧對(duì)不?當(dāng)你的系統(tǒng)啟動(dòng)完畢后你看看你的任務(wù)管理器里是不是有很多進(jìn)程呢?那么多程序是怎么調(diào)如內(nèi)存呢?能理解嗎?這里要明白程序和進(jìn)程的關(guān)系,程序是你磁盤上的一個(gè)文件,當(dāng)你需要它時(shí)進(jìn)入內(nèi)存后才成為進(jìn)程,好比QQ在磁盤上就是一個(gè)文件而已,只有進(jìn)入了內(nèi)存才成為進(jìn)程,進(jìn)程神首搜是活動(dòng)的。QQ要掃描你文件啊,記錄你聊天記錄啊,偷偷上傳個(gè)啥東西什么的你也不知道對(duì)不,他是活動(dòng)的。這個(gè)能明白嗎?
再看作業(yè),這個(gè)作業(yè)可不是你寫作業(yè)的那個(gè)作業(yè)啊。系統(tǒng)一看好家伙你個(gè)QQ那么大的家伙你想一下子進(jìn)入內(nèi)存啊?沒門!慢慢來嘛,系統(tǒng)就把QQ程序分為好幾塊,這幾塊不能亂分的,要符合自然結(jié)構(gòu)就是循環(huán)啦選擇啦這樣的結(jié)構(gòu),你把人家循環(huán)結(jié)構(gòu)咔嚓截?cái)嗔?,怎么讓人家QQ運(yùn)行???這就是作業(yè)要一塊一塊的進(jìn)入內(nèi)存,同時(shí)要為作業(yè)產(chǎn)生JCB(JOB CONTROL BLOCK)作業(yè)控制塊,你進(jìn)入內(nèi)存不能亂跑啊,要聽系統(tǒng)的話,你要是進(jìn)入系統(tǒng)自己的內(nèi)存。框一下,內(nèi)存芹悉不能讀寫 對(duì)話框就出來了,嚴(yán)重點(diǎn)直接藍(lán)臉給你!你懂得。這是window下的,linux下直接給你報(bào)錯(cuò)!沒事了就!所一系統(tǒng)通過jcb控制進(jìn)程。JCB包含了進(jìn)程號(hào)優(yōu)先級(jí)好多內(nèi)容,你打開你的windows任務(wù)管理器看看進(jìn)程是不是有好多屬性???那就是PCB(PRCESS,CONTROL BLOCK)同理作業(yè)也包含那些內(nèi)容只是多少而已。下面寫出進(jìn)程特點(diǎn):
、進(jìn)程是分配計(jì)算機(jī)資源最小的單位。你想啊人是要用程序干活的吧?你把程序調(diào)入內(nèi)存成了就成了進(jìn)程,所以說進(jìn)程是分配資源的最小單位。你在linux下打開終端輸入top命令看是不是有好多進(jìn)程?
2、進(jìn)程有操作系統(tǒng)為作業(yè)產(chǎn)生。有“父進(jìn)程”產(chǎn)生“子進(jìn)程”之間是父子關(guān)系,并可以繼續(xù)向下產(chǎn)生“子進(jìn)程”。還拿QQ來說,你雙擊QQ.exe。QQ啟動(dòng)了輸入賬號(hào)密碼打開主界面了。這時(shí)候你要聊天,QQ進(jìn)程趕緊產(chǎn)生個(gè)“兒子”說 “兒子你去陪主人聊天去吧。這樣子進(jìn)程產(chǎn)生了。突然你想看美女要傳照片這時(shí)候那個(gè)”兒子“有”生“了一個(gè)”兒子“說”兒子“你去傳照片。那個(gè)“兒子領(lǐng)到任務(wù)去傳照片了。這時(shí)你想關(guān)了QQ,QQ提示你說”你還有個(gè)“兒子”和“孫子”還在干活呢你真要結(jié)束嗎?你蒽了確定。QQ對(duì)他“兒子”(你聊天窗口)說:”兒子啊對(duì)不起了,主人要關(guān)閉我你也不能活啊“咔嚓一下”兒子“死了,兒子死之前對(duì)他兒子說:“兒子啊你爺爺不讓我活了,你也別活了咔嚓孫子也死了。最后世界安靜了。這就是進(jìn)程的父子關(guān)系。能明白嗎?記?。哼M(jìn)程之活動(dòng)在內(nèi)存中。不能使用CPU,只管分配資源。
再說線程:線程也產(chǎn)生在內(nèi)存中并且在內(nèi)存中存在相當(dāng)長的時(shí)間,但它的活動(dòng)區(qū)域主要在CPU中,并且運(yùn)行和滅亡都存在于CPU中,可以這么說,線程是程序中能被系統(tǒng)調(diào)度進(jìn)入CPU中最小程序單位,它能直接使用進(jìn)程分配的CPU的資源。
還拿QQ來說當(dāng)你要傳文件時(shí)QQ總要判斷一下文件的擴(kuò)展名吧,ok這時(shí)那個(gè)”兒子“趕緊對(duì)它爸爸說我需要一個(gè)線程判斷擴(kuò)展名QQ趕緊對(duì)一個(gè)管這個(gè)的線程說:”快點(diǎn)去CPU里計(jì)算下那個(gè)擴(kuò)展名是什么然后向主人報(bào)告計(jì)算完了就“死了”消亡了,但是它的線程還在內(nèi)存中!還等著你下一次傳文件然后計(jì)算然后消亡!
線程之間是相互獨(dú)立的。一個(gè)在CPU,一個(gè)在內(nèi)存里還能有關(guān)系嗎對(duì)不?CPU在每一個(gè)瞬間只能進(jìn)入一個(gè)線程,當(dāng)線程進(jìn)入CPU時(shí)立即產(chǎn)生一個(gè)新的線程,新線程仍停留在內(nèi)存中,就好比上面那個(gè)傳文件還會(huì)等著你再傳文件再計(jì)算擴(kuò)展名。
線程相對(duì)線程是獨(dú)立的,但它在內(nèi)存中并不是獨(dú)立的,這就好比你不開QQ能用QQ傳輸文件嗎?它只存在與進(jìn)程分配的資源中,也就是說計(jì)算擴(kuò)展名這個(gè)線程只能停留在QQ這個(gè)進(jìn)程中,不能跑到別的進(jìn)程里?。∠喈?dāng)于程序產(chǎn)生了新的進(jìn)程游歷和線程,進(jìn)程向CPU申請(qǐng)資源,再有線程來使用,他們都是為程序服務(wù)的只是分工不同!
因?yàn)槟銢]提問linux下是怎么管理進(jìn)程和線程的所以我就不回答了,這個(gè)問題我建議你還是看看《笨兔兔的故事》里面講到了linux是怎么管理進(jìn)程和線程的。挺幽默的比我說得還好。
你第二個(gè)問題說實(shí)話我回答不了你!我想你現(xiàn)在連進(jìn)程和線程還沒理解第二個(gè)你更理解不了了你說對(duì)不?我猜的其實(shí)你用C/C++不管是在windows下編程還是在Linux下編程思想都是一樣的對(duì)吧,如果你理解了在windows下線程間通信,在linux更沒問題了!
參考資料:黑客手冊(cè)2023合訂本非安全之一二季244頁,245頁,328頁,329頁,398頁,399頁
淺談操作系統(tǒng)原理 (一 二三)
ubuntu中文論壇 笨兔兔的故事
希望我的回答你能理解
這玩意還真通俗不了,區(qū)別還是很多的,而且每條都能說上大半天。。??梢韵日f下聯(lián)系。首先Linux包括內(nèi)核線程、進(jìn)程、用戶線程這三個(gè)概念,內(nèi)核線程是在linux內(nèi)核中的概念,進(jìn)程通常是都是用戶空間中的概念,但是由于在內(nèi)核中為用戶空間創(chuàng)建進(jìn)程的時(shí)候,和創(chuàng)建內(nèi)核線程是基本一樣的,所以可以說或者可以看成一個(gè)進(jìn)程對(duì)應(yīng)一個(gè)內(nèi)核線程,但還有內(nèi)核線程不是用于服務(wù)進(jìn)程的。而用戶線程不是內(nèi)核的概念,換句話說用戶線程對(duì)于內(nèi)核來說一無所知,所以從這個(gè)角度說進(jìn)程和用戶線程一點(diǎn)關(guān)系都沒有。由于線程通常是由線程庫提供的,例如posix線程庫、cthread線程庫等,這些線程庫是用戶空間動(dòng)態(tài)鏈接庫,所以哪個(gè)進(jìn)程調(diào)用這個(gè)庫,線程以及線程管理、調(diào)度程序就在哪個(gè)進(jìn)程里,不同進(jìn)程調(diào)用的庫所帶來的線程、線程管理都相互無關(guān)。這就是聯(lián)系了?,F(xiàn)在說區(qū)別,討論區(qū)別要分類看,首先是調(diào)度:進(jìn)程調(diào)度由內(nèi)核來調(diào)度,進(jìn)程在內(nèi)核里有內(nèi)核線程來支持,一個(gè)內(nèi)核線程自然包含一套數(shù)據(jù)結(jié)構(gòu)來存儲(chǔ)相關(guān)信息;用戶線程是庫文件支持的,所以數(shù)據(jù)結(jié)構(gòu)定義、調(diào)度函數(shù)都在庫里,當(dāng)然為了提高用戶線程的被調(diào)度的權(quán)限以及實(shí)時(shí)性等優(yōu)勢(shì),有的線程庫已經(jīng)通過一些方式讓內(nèi)核知道用戶線程的存在,這是更遠(yuǎn)的話題了行轎兄。再看內(nèi)存:最常說的一句話就是進(jìn)程有獨(dú)立的內(nèi)存空間而線程沒有,含義是每個(gè)進(jìn)程有自己的一套頁表,一套頁表就意味著一個(gè)完整的內(nèi)存空間,比如32位操作系統(tǒng)里就是2G或者3G的空間(視不同的CPU和操作系統(tǒng)內(nèi)核實(shí)現(xiàn)方式),由于進(jìn)程在內(nèi)核里有自己的地位,所以更換進(jìn)程就能更換整個(gè)頁表;線程在內(nèi)核里沒有地位,所以只要進(jìn)程沒換,線程換檔襲了,頁表還是沒變,所以大家的空間一樣,這個(gè)時(shí)候只能靠程序員自己去保護(hù)各個(gè)線程以及線程庫的能力,舉個(gè)例子:我變了一個(gè)程序a.exe和另一個(gè)程序b.exe,讓b的源碼里有個(gè)函數(shù)叫abc(),在a的源碼里我不可能帆歲直接調(diào)用abc(),因?yàn)榫幾g完了,即使我告訴編譯器abc()函數(shù)在b.exe里的地址給a源碼,在運(yùn)行時(shí)a.exe進(jìn)程空間里的那個(gè)地址放的絕對(duì)不是b里的abc()函數(shù),這時(shí)只能使用遠(yuǎn)程調(diào)用,一個(gè)遠(yuǎn)程調(diào)用的過程基本上和一次網(wǎng)絡(luò)上兩個(gè)機(jī)子傳遞一次數(shù)據(jù)包差不多,可見對(duì)于操作系統(tǒng)來說a和b進(jìn)程里的東西與兩臺(tái)機(jī)子上的東西一樣,相互隔離相互獨(dú)立。這兩類區(qū)別還會(huì)引申出很多細(xì)節(jié)上的區(qū)別,但都?xì)w根于這兩點(diǎn)。希望對(duì)你有幫助
什么是Linux線程?
專業(yè)點(diǎn)的說法,線程被定義為一個(gè)獨(dú)立的指令流,它本身的運(yùn)轉(zhuǎn)由操作系統(tǒng)來安蠢讓銀排,但是,這意味著什么呢?對(duì)軟件開發(fā)者來說,解釋線程更好的描述就是”procedure”可以獨(dú)立于主程序運(yùn)行。再進(jìn)一步,設(shè)想一個(gè)包含了大量procedure的主程序,然后想象所有這些procedure在操作系統(tǒng)的安排下一起或者獨(dú)立的運(yùn)行,這就是對(duì)于多線程程序的一個(gè)簡單描述。問題是,它是如何實(shí)現(xiàn)的呢?在弄懂線程之前,之一步要搞清楚Unix進(jìn)程。進(jìn)程作系統(tǒng)創(chuàng)建,并需帶宴要相當(dāng)多的”開支”,進(jìn)程包含如下程序資源和程序執(zhí)行狀態(tài)信息:進(jìn)程ID,進(jìn)程群組ID,用戶ID,群組ID環(huán)境工作目錄程序指令寄存器棧堆文件描述符信號(hào)動(dòng)作共享庫進(jìn)程間通信工具(例如消息隊(duì)列,管道,信號(hào)量,共享內(nèi)存)
Unix進(jìn)程Unix進(jìn)程內(nèi)部的線程
線程使用和在進(jìn)程內(nèi)的生存,仍由操作系統(tǒng)來安排并且獨(dú)立的實(shí)體來運(yùn)行,很大程度上是因?yàn)樗鼈優(yōu)榭蓤?zhí)行代碼的存在復(fù)制了剛剛好的基本資源。這個(gè)獨(dú)立的控制流之所以可以實(shí)現(xiàn),是因?yàn)榫€程維護(hù)著如下的東西:棧指針寄存器調(diào)度屬性(例如規(guī)則和優(yōu)先級(jí))等待序列和阻塞信號(hào)線程擁有的數(shù)據(jù)
所以,總的來說,Unix環(huán)境里的線程有如下特點(diǎn):它生存在進(jìn)程中,并使用進(jìn)程資源;擁有它自己獨(dú)立的控制流,前提是只要它的父進(jìn)程還存在,并且OS支持它;它僅僅復(fù)制可以使它自己調(diào)度的必要的資源;它可能會(huì)同其它與之同等獨(dú)立的線程分享進(jìn)程資源;如果父進(jìn)程死掉那么它也會(huì)死掉–或者類似的事情;它是輕量級(jí)的,因?yàn)榇蟛糠值拈_支已經(jīng)在它的進(jìn)程創(chuàng)建時(shí)完成了。因?yàn)樵谕贿M(jìn)程內(nèi)的線程分享資源,所以:一個(gè)線程對(duì)共享的系統(tǒng)資源做出的改變(例如關(guān)閉一個(gè)文件)會(huì)被所有的其它線滑嫌程看到;指向同一地址的兩個(gè)指針的數(shù)據(jù)是相同的;對(duì)同一塊內(nèi)存進(jìn)行讀寫操作是可行的,但需要程序員作明確的同步處理操作.
程序的一次執(zhí)行叫一個(gè)進(jìn)程,每個(gè)進(jìn)程有獨(dú)立的堆棧段、代碼段、數(shù)據(jù)段。而且進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的最小單位,多進(jìn)程之間是擁有獨(dú)立的內(nèi)存單元的。
線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,可以和隸屬與同一個(gè)進(jìn)程的其它線程共享進(jìn)程所擁有的全部資源。同一個(gè)進(jìn)程中的多個(gè)線程可以并發(fā)執(zhí)行,多線程之間擁有共享的內(nèi)存單元,迅配悉這樣以提高執(zhí)行效率。
這樣說吧,一個(gè)程序至少包含一個(gè)進(jìn)程,一個(gè)進(jìn)程至少包含一個(gè)線程。
進(jìn)程的創(chuàng)建:fork()
線程的創(chuàng)建:pthread_create()
進(jìn)程間通信主要是管道、賣鎮(zhèn)消息隊(duì)列、信號(hào)量等等,搜縮關(guān)鍵字IPC一大把,這里就不說了。
同一進(jìn)程的線程間通信主要是全局畝乎變量,上面說了,這些線程之間擁有共享的內(nèi)存單元嘛,也就是共享的數(shù)據(jù)段。
而不同進(jìn)程的線程間的通信,主要是借助了進(jìn)程間通信的機(jī)制實(shí)現(xiàn)了啊
linux 線程 共享內(nèi)存的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux 線程 共享內(nèi)存,「Linux 線程的共享內(nèi)存使用」,Linux C++多線程同步的四種方式,麻煩解釋一下linux下進(jìn)程和線程有什么區(qū)別和聯(lián)系,linux下多線程和多進(jìn)程通信的實(shí)現(xiàn)方法,請(qǐng)通俗解釋的信息別忘了在本站進(jìn)行查找喔。
成都網(wǎng)站建設(shè)選創(chuàng)新互聯(lián)(?:028-86922220),專業(yè)從事成都網(wǎng)站制作設(shè)計(jì),高端小程序APP定制開發(fā),成都網(wǎng)絡(luò)營銷推廣等一站式服務(wù)。
網(wǎng)站欄目:「Linux線程的共享內(nèi)存使用」(linux線程共享內(nèi)存)
本文URL:http://www.fisionsoft.com.cn/article/cohjggj.html


咨詢
建站咨詢
