国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Linux系統(tǒng)編程5(線程概念詳解)

這篇具有很好參考價值的文章主要介紹了Linux系統(tǒng)編程5(線程概念詳解)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

線程同進程一樣都是OS中非常重要的部分,線程的應(yīng)用場景非常的廣泛,試想我們使用的視頻軟件,在網(wǎng)絡(luò)不是很好的情況下,通常會采取下載的方式,現(xiàn)在你很想立即觀看,又想下載,于是你點擊了下載并且在線觀看。學(xué)過進程的你會不會想,視頻軟件運行后在OS內(nèi)形成一個進程,有一個執(zhí)行流,但下載和在線觀看是兩件事情,這兩件事情是如何同時進行的呢?你可能會想到CPU的時間片輪轉(zhuǎn),不過曾經(jīng)提到過的時間片輪轉(zhuǎn)是針對進程間的切換的,下載和在線觀看這兩件事本身處于同一個進程內(nèi)完成,你可能還會想到在這個進程內(nèi)創(chuàng)建一個子進程,主進程負責(zé)播放,子進程負責(zé)下載,這確實是一個解決問題的方法,但是創(chuàng)建一個進程所帶來的開銷是不小的。本篇文章將會介紹另一種更加輕便的解決方案——線程,同時我們需要重新理解CPU時間片輪轉(zhuǎn)的調(diào)度單位

目錄

什么是線程

深入理解頁表?

理解進程和線程?

實踐線程操作?

線程終止

線程等待?

分離線程?

線程取消?

TCB

線程的優(yōu)缺點?

優(yōu)點

缺點?

C++提供的線程庫?


什么是線程

按照課本上的定義,線程就是進程內(nèi)部的執(zhí)行流,有多個執(zhí)行流就意味著一個進程可以同時進行多個操作,比如視頻軟件,同時具備播放視頻和下載視頻的功能,如果只有一個執(zhí)行流,那么在播放視頻時就不能同時下載視頻,因為播放視頻和下載視頻的代碼是不同的

以前我們一直認為進程是CPU的調(diào)度單位,現(xiàn)在我們要改變這個看法,被CPU調(diào)度意味著被CPU執(zhí)行,也就是一個執(zhí)行流,一個進程里可以有多個線程,線程才是CPU的調(diào)度單位。所謂的調(diào)度單位就是CPU時間片輪轉(zhuǎn)時的切換單位,以前我們解釋CPU時間片輪轉(zhuǎn)時說的是每個進程都被分配一定的CPU執(zhí)行時間,到達時間,CPU會強制切換到下一個進程,以保證每個進程都能夠被執(zhí)行

此時,通過線程的概念能得知,CPU時間片輪轉(zhuǎn)切換的并不是進程,而是線程。但上面的話并沒有說錯,一是創(chuàng)建一個進程時,默認只有一個執(zhí)行流,也就是只有一個線程,時間片輪轉(zhuǎn)時可以認為是切換進程。二是在后面我們將學(xué)習(xí)到Linux其實并沒有線程的概念,所謂的線程在Linux中是輕量級進程

有些懵沒有關(guān)系,后面會一一解釋原因

現(xiàn)在線程的概念先放到一邊,我們接下來再次回顧曾經(jīng)學(xué)習(xí)過的進程地址空間

深入理解頁表?

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

這是筆者曾經(jīng)多次提到過的進程地址空間映射圖,并且說過虛擬地址空間和物理內(nèi)存之間一一映射,那么大家有沒有思考過這么一個問題,假設(shè)虛擬地址空間有4G大小,物理內(nèi)存也是4G大,而頁表是虛擬地址空間和物理地址空間的一一映射,這意味著頁表自身得有8G大小的空間才能夠滿足虛擬地址空間和物理內(nèi)存之間一一映射,要知道,頁表可也得加載到內(nèi)存中才能讓CPU執(zhí)行,照這樣的映射法,物理內(nèi)存連一個頁表都存不了,更何況4G物理內(nèi)存空間還得留1G給OS呢

可想而知,頁表的映射不會像哈希表那樣一一對應(yīng),要明白頁表的真實構(gòu)造,我們就得從物理內(nèi)存的劃分開始

????Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

實際上物理內(nèi)存是按4kb為單位進行劃分的,每個大小單位被稱為頁框,大家知道磁盤往內(nèi)存中加載數(shù)據(jù)時就是以4kb大小為單位,正好能夠加載到物理內(nèi)存的頁框中,這看似巧妙的背后是前人無數(shù)日夜的精心設(shè)計

但是這好像并沒有說明頁表的真實構(gòu)造,別急,接著往下看

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

真實的頁表并不是只有一張,頁表里存儲的也不是虛擬地址和物理地址的一一對應(yīng),頁表里真正存儲的是物理內(nèi)存中每個頁框的起始地址,一張頁表里只存儲指定數(shù)量的頁框,整個物理內(nèi)存的頁框被多張頁表存儲著

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

這多張頁表被頁目錄記錄著,通過頁目錄可以找到每一張頁表,通過每一張頁表可以找到對應(yīng)的物理內(nèi)存頁框的起始地址。到這里,頁表的整體結(jié)構(gòu)就出來了,可見,當初我們剛了解頁表時,進行了很大程度的簡化。但是這就結(jié)束了嗎?筆者只是把頁表真實的結(jié)構(gòu)給描繪出來,但是并沒有解釋現(xiàn)在的頁表是如何進行映射的?

?Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

上圖是虛擬內(nèi)存中的一個虛擬地址,接下來我們刨析這個虛擬地址如何通過頁表最終映射到物理內(nèi)存?

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

虛擬地址映射到物理內(nèi)存的方法就在地址本身上,通過虛擬地址的前10位可以到頁目錄中找到該地址對應(yīng)在哪個頁表,找到具體的頁表之后,虛擬地址的中間10位標識著該地址在物理內(nèi)存的哪個頁框里,找到具體的頁框之后,那么最后12位想必大家已經(jīng)猜出來了

最后12位正是頁框內(nèi)的偏移地址,因為一個頁框大小就是4kb,要想在某個頁框內(nèi)準確定位,就要知道該頁框的起始地址以及在該頁框內(nèi)的偏移地址。至于對不對,咱們驗證一下

一個地址的大小是4字節(jié),2的12次方是4096,4096 * 4字節(jié) = 4kb,所以驗證正確

如上,真實的頁表映射結(jié)構(gòu)就展現(xiàn)在我們眼前,筆者這里并不是心血來潮講一下頁表,通過上述的過程大家能感受到地址空間是進程接觸并使用資源的窗口,頁表則決定了,進程擁有哪些資源,只有頁表映射到的物理內(nèi)存,進程才能夠訪問,那么通過地址空間+頁表映射進行資源劃分,就可以對一個進程所用的資源進行分類

理解進程和線程?

現(xiàn)在回到對線程的講解上,前面說到過線程是進程內(nèi)部的執(zhí)行流,一個進程可以擁有多個線程,如下圖,這些線程通過使用共同的地址空間和頁表從而共享進程的資源,這意味著一個進程里的多個線程共享該進程的資源

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

前面還提到過,CPU的基本調(diào)度單位是線程,被CPU調(diào)度執(zhí)行,那就得有上下文信息,那么線程就要保存好自己的上下文信息,當被CPU切換執(zhí)行時,可以將上下文信息重新載入到CPU的寄存器中。線程在共享進程資源的同時也會產(chǎn)生自己的執(zhí)行數(shù)據(jù),也是需要保存起來的。線程是CPU調(diào)度的基本單位,這就意味著系統(tǒng)中會存在大量的線程等待被CPU調(diào)用,根據(jù)以往的經(jīng)驗,存在大量的線程時,OS要有序?qū)⑵涔芾砥饋恚偷媒o線程設(shè)計一種數(shù)據(jù)類型,設(shè)計方法還是多次提到過的先描述,再組織

給線程設(shè)計數(shù)據(jù)類型就要考慮線程的id號在系統(tǒng)中唯一,同時要能存儲上下文信息,線程在被CPU調(diào)度時,要有自己的狀態(tài)信息,同時在執(zhí)行過程中要有自己的棧結(jié)構(gòu), 并且線程共享進程資源,那么文件描述符表什么的也要有,越往下舉例,就能明顯感受到這不就是當初學(xué)習(xí)進程時,進程的結(jié)構(gòu)里所包含的內(nèi)容嗎?

可以發(fā)現(xiàn)進程結(jié)構(gòu)和線程結(jié)構(gòu)大量的內(nèi)容都是重疊的,如果進程和線程兩種結(jié)構(gòu)同時存在系統(tǒng)中,就會造成大量的冗余,而Linux是一個非常注重效率的OS,于是聰明的Linux設(shè)計者決定不為線程設(shè)計一個獨立的結(jié)構(gòu),而是采用了輕量級進程結(jié)構(gòu),也就是說在Linux系統(tǒng)中,進程和線程實際上使用的是同一種結(jié)構(gòu)

這一點與windows有很大的不同,windows就為線程設(shè)計了一個獨立的結(jié)構(gòu),這也體現(xiàn)了兩種OS各自的設(shè)計哲學(xué)

如何理解線程就是輕量級進程呢?如何理解現(xiàn)在的進程概念呢?

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

曾經(jīng)我們認為一個task_struct就是一個進程,一個task_struct有一個執(zhí)行流,并且記錄著該執(zhí)行信息的執(zhí)行狀態(tài)?,F(xiàn)在學(xué)了線程,知道進程和線程共同使用task_struct結(jié)構(gòu),對于每個進程或線程,內(nèi)核都會為其分配一個唯一的task_struct結(jié)構(gòu),現(xiàn)在的task_struct是一種輕量級進程,也就是說一個進程里可能含有多個task_struct,不能再將一個task_struct理解成一個進程。但這并不是說曾經(jīng)學(xué)的就是錯誤的。曾經(jīng)創(chuàng)建一個進程,默認有一個執(zhí)行流,也就是有一個主線程,該主線程是創(chuàng)建進程本身的執(zhí)行流,task_struct就是這個主線程的結(jié)構(gòu),故而也可以將task_struct理解成進程本身,但是多線程后,有多個task_struct,再按照以前的方法理解進程就顯得不嚴謹了

假設(shè)現(xiàn)在一個進程創(chuàng)建了三個線程,那么會有幾個task_struct呢?

如果一個進程創(chuàng)建了三個線程,那么通常會有四個task_struct結(jié)構(gòu),在Linux中,每個進程都有一個主線程,也就是創(chuàng)建該進程的線程,主線程有一個對應(yīng)的task_struct結(jié)構(gòu),對于每個創(chuàng)建的子線程,也會有一個對應(yīng)的task_struct結(jié)構(gòu)。 故而,對于一個進程而言,如果額外創(chuàng)建了三個子線程,那么會有一個主線程的task_struct結(jié)構(gòu),以及三個子線程的task_struct結(jié)構(gòu),共計四個task_struct結(jié)構(gòu),這四個task_struct結(jié)構(gòu)共同構(gòu)成了該進程的線程組成部分

站在CPU的角度上,曾經(jīng)時間片輪轉(zhuǎn)時切換task_struct就是切換一個進程,現(xiàn)在CPU時間片輪轉(zhuǎn)切換一個task_struct是切換進程的一個分支,如果這個進程只有一個主線程,那就是切換進程本身

總而言之,現(xiàn)在一個進程有多個執(zhí)行流,進程的概念不能局限于曾經(jīng)只有一個執(zhí)行流的task_struct,而是一個擁有多個task_struct的承擔(dān)分配系統(tǒng)資源的基本實體

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

實踐線程操作?

說了這么多,咱們連線程長什么樣子都不知道,接下來咱們通過實踐來感受線程的魅力

不過在動手敲代碼之前,需要明確一些事情,因為用輕量級進程來表示線程是Linux系統(tǒng)獨特的線程處理方式。雖然這能很大提高效率,但是也帶來了不通用的麻煩,很多OS,包括OS的理論基礎(chǔ)上都是有線程這個概念的,因此并不通用Linux的輕量級進程,大家都在使用線程接口,而你Linux搞特殊提供輕量級進程接口,大家是不認的,為了解決這個問題,Linux工程師就將輕量級進程接口進行封裝,適配成大家都通用的線程接口

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

這意味著,我們在使用Linux線程接口時,要在編譯時帶上線程動態(tài)庫即選項 -l pthread

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

創(chuàng)建一個線程是通過接口

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);

頭文件:pthread.h? ?
參數(shù)
thread:返回線程ID (輸出型參數(shù))
attr:設(shè)置線程的屬性,attr為NULL表示使用默認屬性
start_routine:是個函數(shù)指針,線程啟動后要執(zhí)行的函數(shù)
arg:傳給線程啟動函數(shù)的參數(shù)
返回值:成功返回0;失敗返回錯誤碼

第一個參數(shù)是一個輸出型參數(shù),我們在主函數(shù)里創(chuàng)建一個pthread_t類型的變量,將其的地址傳過去,創(chuàng)建線程后,會把該線程的id寫入到這個pthread_t類型變量里

我們目前不需要關(guān)心 att r這個參數(shù),可以看到第三個參數(shù)是一個函數(shù)指針,其所指向的函數(shù)就是創(chuàng)建一個線程后,該線程去執(zhí)行的任務(wù)

第四個參數(shù)是對第三個參數(shù)的補充,在我們編寫線程要執(zhí)行的函數(shù)時,有時是需要外部給這個函數(shù)傳參的,那個這個函數(shù)就會默認有一個void* 類型的參數(shù),這個參數(shù)就是通過pthread_create的第四個參數(shù)傳遞過去的

下面看一個線程代碼示例

#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<cstring>
#include<cstdlib>
#include<cstdio>

using namespace std;

void* start_routine(void * arg)
{
      while(true){
        printf("%s\n", (char*)arg);
        sleep(1);
      }
}

int main()
{
    pthread_t thread_id;
    char buff[64];
    snprintf(buff, sizeof(buff), "我是新創(chuàng)建的線程,我正在運行");
    
    pthread_create(&thread_id, nullptr, start_routine, (void*)buff);

    int counter = 10;
    while(counter--){
        printf("我是主線程,運行倒計時:%d\n", counter);
        sleep(1);
    }

    return 0;
}

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

這個示例可以看到,真的有兩個執(zhí)行流同時在跑

通過命令ps -aL可以查看所有進程內(nèi)的線程,接下來我們讓兩個線程不間斷運行,然后查看這兩個線程的相關(guān)信息

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

可以發(fā)現(xiàn),當test程序跑起來后,出現(xiàn)了兩個test線程,這兩個線程的PID是相同的,說明這兩個線程來自同一個進程,不過兩個線程的LWP不同,LWP(light weight process,即輕量級進程)LWP就是所謂的線程ID了,并且第一個線程的PID和LWP相同,這說明該線程是主線程,CPU在調(diào)度時,是以LWP為標識,表示一個特定的執(zhí)行流

上面只是創(chuàng)建單個線程,那么如何同時創(chuàng)建多個線程呢?

看下面的demo,我們一次創(chuàng)建10個線程,并且不停打印他們的序號

#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<cstring>
#include<cstdlib>

using namespace std;

#define MAX 10

void* _start_test(void* arg){

    while(true){
        sleep(1);
        cout << (char*)arg << endl;
    }
    return nullptr;
}


int main(){

    for (int i = 0; i<MAX; i++){
        pthread_t tid;
        char buff[64];
        snprintf(buff, sizeof(buff), "this is %d thread", i);
        pthread_create(&tid, nullptr, _start_test, buff);
    }

    while(true){
        sleep(1);
        cout << "我是主線程"<<endl;
    }

    return 0;
}

?Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

當執(zhí)行結(jié)果出來后,完全超出了我們的預(yù)期,我們本想這10個線程,各自打印各自的序號,可是結(jié)果每個線程都打印序號9

出現(xiàn)這種情況的原因是線程被創(chuàng)建后的執(zhí)行順序是不確定的,當?shù)谝粋€被創(chuàng)建的進程還沒來得及執(zhí)行它的start_routine函數(shù)時,主線程就已經(jīng)把所有的線程都創(chuàng)建完畢了,buff是在循環(huán)里被被創(chuàng)建的,出了循環(huán)后就被銷毀,然后再次創(chuàng)建,因為都是在main函數(shù)棧里,所以每次buff的地址都不變,且buff的值不斷被覆寫,直到最后一個線程創(chuàng)建完畢,buff的值被覆寫為序號9

此時循環(huán)退出,buff也被銷毀了,但是由于main函數(shù)這個棧還在,也沒有開其他的棧,因此原先buff指向的空間并沒有被清理,導(dǎo)致所有的線程都打印最后一次覆寫buff的內(nèi)容,通過這個demo,可得知線程除了獨自的PCB,獨自的上下文結(jié)構(gòu),獨自的棧結(jié)構(gòu),其他幾乎所有內(nèi)容都是共享的

每一個線程都有自己獨立的棧,這是因為一個線程在執(zhí)行時,可能會調(diào)用各種函數(shù),因此需要一個獨立的棧,這個棧里的內(nèi)容不與其他線程共享

線程終止

會創(chuàng)建線程之后,自然而然的會想到,線程如何終止,導(dǎo)致線程終止的原因有很多

1.執(zhí)行完start_routine()后,線程會自動return結(jié)束

2.使用pthread_exit()來終止當前線程,但是要注意,不要習(xí)慣性的使用exit()來終止線程,exit()是用來終止進程的,進程終止,該進程內(nèi)所有的線程都會終止

3.某個線程執(zhí)行過程中,出現(xiàn)錯誤,觸發(fā)OS檢查,會給當前線程的進程發(fā)送信號,進程收到信號會終止,該進程內(nèi)其他所有線程都會終止

4.?一個線程可以調(diào)用pthread_ cancel()終止同一進程中的另一個線程

線程等待?

同進程一樣,線程結(jié)束后其所申請的各種資源都是需要被回收的,不然會產(chǎn)生類似僵尸進程一樣的問題,線程等待使用函數(shù)pthread_join()

int pthread_join(pthread_t thread, void **retval);

第一個參數(shù)就是被等待的線程id,第二個參數(shù)是獲取該線程的返回值的,還記得start_routine有一個void* 返回值嗎?這個返回值就是通過pthread_join獲取的

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

注意:OS維護的是輕量級進程PCB,因為Linux特殊的線程方案,可以說沒有線程概念。程序員日常使用習(xí)慣了線程接口,因此Linux提供了線程庫,線程庫負責(zé)線程接口與輕量級進程接口之間的轉(zhuǎn)換,以及維護用戶通過接口創(chuàng)建好的線程

分離線程?

默認情況下,新創(chuàng)建的線程是joinable的,線程退出后,需要對其進行pthread_join操作,否則無法釋放資源,從而造成系統(tǒng)泄漏
如果不關(guān)心線程的返回值,join是一種負擔(dān),這個時候,我們可以告訴系統(tǒng),當線程退出時,自動釋放線程資源
使用接口:int pthread_detach(pthread_t thread);
可以是線程組內(nèi)其他線程對目標線程進行分離,也可以是線程自己分離
pthread_detach(pthread_self());? ?pthread_self()獲取自己的線程id

?需要注意的是,一旦一個線程已經(jīng)處于分離狀態(tài),那么該線程就不能被等待

線程取消?

線程取消也就是當線程跑起來后,我們通過主線程或者其他線程可以取消這個線程繼續(xù)運行

也可以自己取消自己

int pthread_cancel(pthread_t thread);

返回值:成功返回0;失敗返回錯誤碼

注意:只有當該進程運行起來,有自己的線程ID時才可以被取消

TCB

PCB是Linux內(nèi)核用來管理輕量級進程的內(nèi)核,因為Linux沒有線程的概念,程序員要使用線程的接口,因此要通過線程庫進行轉(zhuǎn)接,那么程序員每申請一個線程,線程庫就得維護好這個線程和輕量級進程進行轉(zhuǎn)換,那么TCB就是線程庫維護線程的結(jié)構(gòu)

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux?Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux?

由圖中可以得知,我們接收的所謂的線程id值其實就是庫中維護的該線程TCB的起始地址?

線程的優(yōu)缺點?

優(yōu)點

線程的使用能非常大程度上發(fā)揮多核CPU的實力,并且創(chuàng)建多個線程比創(chuàng)建多個進程的開銷要小的多,為什么呢?

如果CPU執(zhí)行時,要切換一個進程,那么要切換的內(nèi)容至少包含頁表,虛擬地址空間,PCB,上下文數(shù)據(jù)

而切換一個線程,那么只需要切換PCB,上下文數(shù)據(jù)等主要內(nèi)容

CPU在執(zhí)行一個進程時,會在寄存器中緩存該進程的很多熱點數(shù)據(jù),例如虛擬地址空間,頁表等,一旦切換進程,這些熱點數(shù)據(jù)要全部重新加載,而切換線程,這些數(shù)據(jù)不需要動

缺點?

在運行計算密集型程序時,線程需要不停的計算,持續(xù)占有CPU,切換到其它線程的時間就會延長,導(dǎo)致效率低下

使用多線程編程會有互斥和同步等問題,程序的編寫和維護成本很高

C++提供的線程庫?

雖說Linux提供了線程庫,但是Linux的線程接口和Windows下的線程接口很多都是不同的,這就導(dǎo)致程序的可移植性很低,?C++11之后,在語言層面上對Linux和windows平臺下的線程接口再進行一次封裝。如此以來,用C++線程庫編寫的多線程程序可以同時在這兩個OS平臺下執(zhí)行,代碼的可移植性大大提高

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

下面的demo簡單演示了如何使用C++提供的線程庫,這部分屬于C++的知識了,筆者將在C++專欄中介紹其詳細使用方法

#include<thread>
#include<iostream>
#include<unistd.h>

using namespace std;

void* start_routine()
{
    int counter = 10;

    while(counter--){
        sleep(1);
        cout << "我是新創(chuàng)建的線程,運行倒計時:" << counter <<endl;
    }

    return nullptr;
}


int main()
{
    //創(chuàng)建一個線程,并把執(zhí)行函數(shù)傳遞過去
    thread t1(start_routine);

    cout << "我是主線程" <<endl;

    //主線程阻塞等待回收子線程
    t1.join();
    cout << "線程回收完畢,準備退出"<<endl;
    return 0;
}

Linux系統(tǒng)編程5(線程概念詳解),Linux(基礎(chǔ)使用,系統(tǒng)編程,網(wǎng)絡(luò)編程),linux

文章的最后,大家可以嘗試自己模仿C++的線程庫,對Linux的線程庫再進行一次封裝?文章來源地址http://www.zghlxwxcb.cn/news/detail-692030.html

到了這里,關(guān)于Linux系統(tǒng)編程5(線程概念詳解)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • C++開發(fā)基礎(chǔ)之網(wǎng)絡(luò)編程WinSock庫使用詳解TCP/UDP Socket開發(fā)

    Winsock是Windows操作系統(tǒng)提供的用于網(wǎng)絡(luò)編程的API庫。它是Windows Sockets的簡稱,也就是套接字庫。Winsock可以讓開發(fā)人員使用TCP/IP協(xié)議族中的各種協(xié)議,如TCP、UDP等,在Windows平臺下進行網(wǎng)絡(luò)編程。 Winsock提供了一組函數(shù)和數(shù)據(jù)結(jié)構(gòu),這些函數(shù)和數(shù)據(jù)結(jié)構(gòu)可以讓開發(fā)人員創(chuàng)建和管理

    2024年01月23日
    瀏覽(25)
  • Linux 網(wǎng)絡(luò)編程 和 字節(jié)序的概念

    Linux 網(wǎng)絡(luò)編程 和 字節(jié)序的概念

    不同于之前學(xué)習(xí)的所有通訊方法,多基于Linux內(nèi)核實現(xiàn),只能在同一個系統(tǒng)中不同進程或線程間通訊, Linux的網(wǎng)絡(luò)編程可以實現(xiàn)真正的 多機通訊! 兩個不相關(guān)的終端要實現(xiàn)通訊,必須依賴網(wǎng)絡(luò),通過 地址 來找到對方,所謂地址包含的兩個重要概念就是? IP地址 和 端口號 。

    2024年02月11日
    瀏覽(33)
  • 【Linux網(wǎng)絡(luò)編程】高并發(fā)服務(wù)器框架 線程池介紹+線程池封裝

    【Linux網(wǎng)絡(luò)編程】高并發(fā)服務(wù)器框架 線程池介紹+線程池封裝

    前言 一、線程池介紹 ??線程池基本概念 ??線程池組成部分 ??線程池工作原理? 二、線程池代碼封裝 ??main.cpp ??ThreadPool.h ??ThreadPool.cpp ??ChildTask.h? ??ChildTask.cpp ??BaseTask.h ??BaseTask.cpp 三、測試效果 四、總結(jié) ??創(chuàng)建線程池的好處 本文主要學(xué)習(xí) Linux內(nèi)核編程 ,結(jié)合

    2024年01月16日
    瀏覽(33)
  • [Linux] 網(wǎng)絡(luò)編程 - 初見TCP套接字編程: 實現(xiàn)簡單的單進程、多進程、多線程、線程池tcp服務(wù)器

    [Linux] 網(wǎng)絡(luò)編程 - 初見TCP套接字編程: 實現(xiàn)簡單的單進程、多進程、多線程、線程池tcp服務(wù)器

    網(wǎng)絡(luò)的上一篇文章, 我們介紹了網(wǎng)絡(luò)變成的一些重要的概念, 以及 UDP套接字的編程演示. 還實現(xiàn)了一個簡單更簡陋的UDP公共聊天室. [Linux] 網(wǎng)絡(luò)編程 - 初見UDP套接字編程: 網(wǎng)絡(luò)編程部分相關(guān)概念、TCP、UDP協(xié)議基本特點、網(wǎng)絡(luò)字節(jié)序、socket接口使用、簡單的UDP網(wǎng)絡(luò)及聊天室實現(xiàn)…

    2024年02月16日
    瀏覽(32)
  • Linux網(wǎng)絡(luò)編程:多進程 多線程_并發(fā)服務(wù)器

    文章目錄: 一:wrap常用函數(shù)封裝 wrap.h? wrap.c server.c封裝實現(xiàn) client.c封裝實現(xiàn) 二:多進程process并發(fā)服務(wù)器 server.c服務(wù)器 實現(xiàn)思路 代碼邏輯? client.c客戶端 三:多線程thread并發(fā)服務(wù)器 server.c服務(wù)器 實現(xiàn)思路 代碼邏輯? client.c客戶端 ???? ??read 函數(shù)的返回值 wrap.h? wrap

    2024年02月12日
    瀏覽(31)
  • 【探索Linux】P.25(網(wǎng)絡(luò)編程套接字基本概念 —— 預(yù)備知識)

    【探索Linux】P.25(網(wǎng)絡(luò)編程套接字基本概念 —— 預(yù)備知識)

    在上一篇文章中,我們深入探討了Linux網(wǎng)絡(luò)的基礎(chǔ)知識和它的發(fā)展歷史,為讀者揭開了Linux網(wǎng)絡(luò)技術(shù)演變的序幕。我們了解到,Linux網(wǎng)絡(luò)技術(shù)的發(fā)展不僅促進了操作系統(tǒng)本身的成熟,還對整個互聯(lián)網(wǎng)的進步產(chǎn)生了深遠的影響。隨著網(wǎng)絡(luò)技術(shù)的不斷進步,Linux系統(tǒng)在網(wǎng)絡(luò)通信方面

    2024年04月27日
    瀏覽(95)
  • 【探索Linux】—— 強大的命令行工具 P.26(網(wǎng)絡(luò)編程套接字基本概念—— socket編程接口 | socket編程接口相關(guān)函數(shù)詳細介紹 )

    【探索Linux】—— 強大的命令行工具 P.26(網(wǎng)絡(luò)編程套接字基本概念—— socket編程接口 | socket編程接口相關(guān)函數(shù)詳細介紹 )

    本文將深入探討使用套接字進行網(wǎng)絡(luò)通信的基本步驟,包括創(chuàng)建套接字、綁定地址、監(jiān)聽連接(對于服務(wù)器端)、連接遠程主機(對于客戶端)、以及發(fā)送和接收數(shù)據(jù)等操作。套接字編程涉及一系列系統(tǒng)調(diào)用和函數(shù),如 socket() 、 bind() 、 listen() 、 connect() 、 send() 、 recv() 等。

    2024年03月10日
    瀏覽(102)
  • Linux:概述 、安裝 、文件與目錄結(jié)構(gòu) 、vim編輯器 、網(wǎng)絡(luò)配置 、遠程登錄 、系統(tǒng)管理 、基礎(chǔ)命令 、軟件包管理 、克隆虛擬機 、shell編程

    Linux:概述 、安裝 、文件與目錄結(jié)構(gòu) 、vim編輯器 、網(wǎng)絡(luò)配置 、遠程登錄 、系統(tǒng)管理 、基礎(chǔ)命令 、軟件包管理 、克隆虛擬機 、shell編程

    2.1.1、Linux是什么? Linux是一個操作系統(tǒng)(OS) 所謂的操作系統(tǒng)就是直接用來操作計算機底層硬件的軟件。 2.1.2、Linux的出現(xiàn) 官網(wǎng): https://www.centos.org/ 進入官網(wǎng)進行下載 有很多的鏡像,以阿里云的為例: 3.3.1、下載 官網(wǎng): https://www.vmware.com/ 這是下載的企業(yè)版,30天試用期,可

    2024年02月05日
    瀏覽(60)
  • Linux網(wǎng)絡(luò)編程:socket & pthread_create()多線程 實現(xiàn)clients/server通信

    Linux網(wǎng)絡(luò)編程:socket & pthread_create()多線程 實現(xiàn)clients/server通信

    UNIX網(wǎng)絡(luò)編程:socket fork()多進程 實現(xiàn)clients/server通信 隨筆介紹了通過fork()多進程實現(xiàn)了服務(wù)器與多客戶端通信。但除了多進程能實現(xiàn)之外,多線程也是一種實現(xiàn)方式。 重要的是,多進程和多線程是涉及操作系統(tǒng)層次。隨筆不僅要利用pthread_create()實現(xiàn)多線程編程,也要理解線

    2024年02月05日
    瀏覽(23)
  • 一、網(wǎng)絡(luò)編程之基礎(chǔ)知識詳解

    一、網(wǎng)絡(luò)編程之基礎(chǔ)知識詳解

    引言: 初學(xué)網(wǎng)絡(luò)編程時會涉及到許多網(wǎng)絡(luò)基礎(chǔ)知識,這些知識點比較零碎,本文希望系統(tǒng)總結(jié)一次,以便在后續(xù)的學(xué)習(xí)和工作中能夠快速查閱。 網(wǎng)絡(luò)分層模型 OSI 七層模型 OSI 模型,也叫做七層模型, OSI 是 Open System Interconnection 的縮寫,譯為“開放式系統(tǒng)互聯(lián)”。 OSI 模型是

    2024年02月09日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包