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

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局

這篇具有很好參考價(jià)值的文章主要介紹了【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

OS提供的輕量級進(jìn)程接口

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
(關(guān)于 用戶 → 庫 → OS :具體可看下面線程地址空間布局)

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

這個(gè)clone我們不用,這是OS提供給第三方庫所用的接口

POSIX線程庫

與線程有關(guān)的函數(shù)構(gòu)成了一個(gè)完整的系列,絕大多數(shù)函數(shù)的名字都是以“pthread_”開頭的,要使用這些函數(shù)庫,要通過引入頭文<pthread.h>,鏈接這些線程函數(shù)庫時(shí)要使用編譯器命令的“-lpthread”選項(xiàng)

創(chuàng)建線程:
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
函數(shù)原型:

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

參數(shù)

  • thread:返回線程ID
  • attr:設(shè)置線程的屬性,attr為NULL表示使用默認(rèn)屬性
  • start_routine:是個(gè)函數(shù)地址,線程啟動(dòng)后要執(zhí)行的函數(shù)
  • arg:傳給線程啟動(dòng)函數(shù)的參數(shù)

返回值:成功返回0;失敗返回錯(cuò)誤碼

錯(cuò)誤檢查:

  • 傳統(tǒng)的一些函數(shù)是,成功返回0,失敗返回-1,并且對全局變量errno賦值以指示錯(cuò)誤。
  • pthreads函數(shù)出錯(cuò)時(shí)不會(huì)設(shè)置全局變量errno(而大部分其他POSIX函數(shù)會(huì)這樣做)。而是將錯(cuò)誤代碼通過返回值返回
  • pthreads同樣也提供了線程內(nèi)的errno變量,以支持其它使用errno的代碼。對于pthreads函數(shù)的錯(cuò)誤,
    建議通過返回值業(yè)判定,因?yàn)樽x取返回值要比讀取線程內(nèi)的errno變量的開銷更小

線程使用

1.如何創(chuàng)建一堆線程

試驗(yàn):創(chuàng)建一批線程:

#include <iostream>
#include <string>
#include <vector>
#include <pthread.h>
#include <unistd.h>

using namespace std;
void *start_routine(void *args)
{
    string name = static_cast<const char *>(args);
    while (true)
    {
        cout << "new thread create success , name: " << name << endl;
        sleep(1);
    }
}
int main()
{
    vector<pthread_t> tids;
#define NUM 10
    for (int i = 0; i < NUM; i++)
    {
        pthread_t tid;
        char namebuffer[64];
        snprintf(namebuffer, sizeof(namebuffer), "%s:%d", "thread", i);
        pthread_create(&tid, nullptr, start_routine, namebuffer);
        // sleep(1);
    }
    while (true)
    {
        cout << "new thread create success , name: main thread" << endl;
        sleep(1);
    }
    return 0;
}

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

為什么這里連續(xù)輸出9呢?
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

我們這樣的寫法是有問題的,我們可以對其進(jìn)行更改:

class ThreadData
{
public:
    int number;
    pthread_t tid;
    char namebuffer[64];
};
void *start_routine(void *args)
{
    ThreadData *td = static_cast<ThreadData *>(args); // 安全的進(jìn)行強(qiáng)制類型轉(zhuǎn)化
    int cnt = 10;
    while (cnt)
    {
        cout << "new thread create success, name: " << td->namebuffer << " cnt: " << cnt-- << endl;
    }
    delete td;
    return nullptr;
}
int main()
{
    vector<ThreadData *> threads;
#define NUM 10
    for (int i = 0; i < NUM; i++)
    {
        ThreadData *td = new ThreadData();
        td->number = i + 1;
        snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i + 1);
        pthread_create(&td->tid, nullptr, start_routine, td);
        threads.push_back(td);
    }
    for (auto &iter : threads)
    {
        cout << "create thread: " << iter->namebuffer << " : " << iter->tid << " suceesss" << endl;
    }
    while (true)
    {
        cout << "new thread create success , name: main thread" << endl;
        sleep(1);
    }
    return 0;
}

將其創(chuàng)建成結(jié)構(gòu)體,每次創(chuàng)建都new一個(gè)ThreadData對象,然后將結(jié)構(gòu)體對象的地址傳遞給start_routine,每一個(gè)結(jié)構(gòu)體對象都有自己獨(dú)立的緩沖區(qū),這樣就能避免緩沖區(qū)被刷新了的問題。
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

思考:start_routine這個(gè)函數(shù)被10個(gè)線程同時(shí)運(yùn)行,它是什么狀態(tài)?函數(shù)里面定義的tdcnt在變化會(huì)影響別的線程嗎?
start_routine這個(gè)函數(shù)現(xiàn)在是重入狀態(tài),該函數(shù)是可重入函數(shù),雖然cnt在變化,但是在函數(shù)內(nèi)定義的變量,都叫做局部變量,具有臨時(shí)性,現(xiàn)在依舊適用在多線程情況下,也沒有問題。其實(shí)每一個(gè)線程都有自己獨(dú)立的棧結(jié)構(gòu)!(打印輸出現(xiàn)在不解釋,這個(gè)輸出是往文件輸出,當(dāng)然只能執(zhí)行一個(gè))

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

2.線程如何終止

  1. return nullptr;線程函數(shù)結(jié)束,return的時(shí)候,線程就算終止了
  2. pthread_exit(nullptr);我們在start_routine函數(shù)while循環(huán)中終止:
void *start_routine(void *args)
{
    sleep(1);
    ThreadData *td = static_cast<ThreadData *>(args); // 安全的進(jìn)行強(qiáng)制類型轉(zhuǎn)化
    int cnt = 10;
    while (cnt)
    {
        cout << "cnt : " << cnt << " &cnt: " << &cnt << endl;
        cnt--;
        pthread_exit(nullptr);//終止線程
        sleep(1);
    }
    delete td;
    return nullptr;
}

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
循環(huán)打印線程腳本:

while :; do ps -aL | head -1 && ps -aL | grep mythread;sleep 1;done

我們不能之間在線程中使用exit(),因?yàn)檫@是直接終止進(jìn)程的,如果有線程調(diào)用這個(gè)函數(shù),那么整個(gè)線程都會(huì)終止,pthread_exit(nullptr);可以終止新線程而不影響主線程。

3.線程如何取消

線程是可以被取消的但是注意:線程要被取消,前提是這個(gè)線程已經(jīng)跑起來了
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
函數(shù)原型:

int pthread_cancel(pthread_t thread);

實(shí)操代碼:

//新線程部分代碼
void* start_routine(void *args)
{
	//....
    return (void*)123;
}
//主線程部分代碼
for(int i = 0; i < threads.size()/2; i++)
{
    pthread_cancel(threads[i]->tid);
    cout << "pthread_cancel : " << threads[i]->namebuffer << " success" << endl;
}
for (auto &iter : threads)
{
    void* tmp=nullptr;
    int n = pthread_join(iter->tid, &tmp);
    assert(n == 0);
    cout << "join thread : " << iter->namebuffer <<"exit : "<< (long long)tmp << endl;
    delete iter;
}

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
線程如果是被取消的,退出碼:-1(PTHREAD_CANCELED)


線程等待

線程也是要被等待的,如果不等待,會(huì)造成類似僵尸進(jìn)程的問題–內(nèi)存泄漏

線程必須也要被等待:

  1. 獲取新線程的退出信息→可以不關(guān)心退出信息嗎?可以
  2. 回收新線程對應(yīng)的PCB等內(nèi)核資源,防止內(nèi)存泄漏 – 暫時(shí)無法查看!

線程等待函數(shù)pthread_join:
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
函數(shù)原型:

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

在主線程中等待并釋放:

for (auto &iter : threads)
{
    int n = pthread_join(iter->tid,nullptr);
    assert(n ==0);
    cout << "join thread : " << iter->namebuffer << " success" << endl;
    delete iter;
}

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器


線程退出返回值

我們的start_routine函數(shù)返回值是void*類型,這個(gè)類型有什么說法嗎?
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

//新線程部分代碼
void *start_routine(void *args)
{
    //....
    return (void*)123;
}
//主線程部分代碼:
for (auto &iter : threads)
{
    void* tmp=nullptr;
    int n = pthread_join(iter->tid, &tmp);
    assert(n == 0);
    cout << "join thread : " << iter->namebuffer <<"exit : " << (long long)tmp<< " success" << endl;//(long long)類型是因?yàn)槲沂褂玫腖inux版本是64位的
    delete iter;
}
//其余代碼跟之前一樣,這里只是增加的或更改了一點(diǎn)

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

這個(gè)的返回值也跟上述return是一樣的

pthread_exit((void*)123);

既然假的地址,整數(shù)都能被外部拿到,那么如何返回的是,堆空間的地址呢?對象的地址呢?
返回一個(gè)對象指針:

class ThreadReturn
{
public:
    int exit_code;
    int exit_result;
};
//新線程部分代碼
void* start_routine(void *args)
{
	//.....
    ThreadReturn * tr = new ThreadReturn();
    tr->exit_code = 1;
    tr->exit_result = 123;
    return (void*)tr;
}
//主線程部分代碼
for (auto &iter : threads)
{
    ThreadReturn* tmp=nullptr;
    int n = pthread_join(iter->tid, (void**)&tmp);
    assert(n == 0);
    cout << "join thread : " << iter->namebuffer <<"exit_code : " << tmp->exit_code<< " exit_result : "<<tmp->exit_result << endl;
    delete iter;
}

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

為什么沒有見到,線程退出的時(shí)候,對應(yīng)的退出信號???
線程出異常,收到信號,整個(gè)進(jìn)程都會(huì)退出!pthread_join:默認(rèn)就認(rèn)為函數(shù)會(huì)調(diào)用成功!不考慮異常問題,異常問題是進(jìn)程該考慮的問題!


C++11的多線程

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

void thread_run()
{
    while (true)
    {
        std::cout << "我是新線程..." << std::endl;
        sleep(1);
    }
}

int main()
{
    std::thread t1(thread_run);

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

    t1.join();

    return 0;
}

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
任何語言,在linux中如果要實(shí)現(xiàn)多線程,必定要是用pthread庫

如何看待C++11中的多線程呢?
C++11 的多線程,在Linux環(huán)境中,本質(zhì)是對pthread庫的封裝!(使用原生線程庫還是C++11的線程庫都可以,只是C++11的線程庫在windows下也能運(yùn)行,Linux與windows底層的線程庫的接口不一樣)


線程ID及地址空間布局

  • pthread_create函數(shù)會(huì)產(chǎn)生一個(gè)線程ID,存放在第一個(gè)參數(shù)指向的地址中。該線程ID和前面說的線程ID不是一回事。
  • 前面講的線程ID屬于進(jìn)程調(diào)度的范疇。因?yàn)榫€程是輕量級進(jìn)程,是操作系統(tǒng)調(diào)度器的最小單位,所以需要一個(gè)數(shù)值來唯一表示該線程。
  • pthread_create函數(shù)第一個(gè)參數(shù)指向一個(gè)虛擬內(nèi)存單元,該內(nèi)存單元的地址即為新創(chuàng)建線程的線程ID,屬于NPTL線程庫的范疇。線程庫的后續(xù)操作,就是根據(jù)該線程ID來操作線程的。
  • 線程庫NPTL提供了pthread_self函數(shù),可以獲得線程自身的ID

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>

std::string changeId(const pthread_t &thread_id)
{
    char tid[128];
    snprintf(tid, sizeof(tid), "0x%x", thread_id);
    return tid;
}

void *start_routine(void *args)
{
    std::string threadname = static_cast<const char *>(args);
    while (true)
    {
        std::cout << threadname << " running ... : " << changeId(pthread_self()) << std::endl;
        sleep(1);
    }

    return nullptr;
}
int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, start_routine, (void *)"thread 1");
    std::string main_id = changeId(pthread_self());
    std::cout << "main thread running ... new thread id: " << changeId(tid) <<" main thread id: " << main_id << std::endl;
    pthread_join(tid,nullptr);
    return 0;
}

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

線程地址空間布局

pthread_t 到底是什么類型呢?取決于實(shí)現(xiàn)。對于Linux目前實(shí)現(xiàn)的NPTL實(shí)現(xiàn)而言,pthread_t類型的線程ID,本質(zhì)就是一個(gè)進(jìn)程地址空間上的一個(gè)地址。

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
原生線程庫可能存在多個(gè)線程,我們同樣也要對線程進(jìn)行管理(先描述再組織),每一個(gè)輕量級進(jìn)程對應(yīng)原生庫中的一個(gè)結(jié)構(gòu)體對象(TCB),這是Linux的方案 – 用戶級線程,用戶關(guān)心的線程屬性在庫中,而內(nèi)核里面提供執(zhí)行流的調(diào)度。Linux用戶級線程對比內(nèi)核輕量級進(jìn)程是1:1。

線程布局圖:
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

用戶級線程:線程ID值就是庫中結(jié)構(gòu)體(TCB)對象的地址

線程局部存儲(chǔ)

我們在之前的“什么是線程?”一文已經(jīng)了解到了:線程一旦被創(chuàng)建,幾乎所有資源都是被線程所共享的

//定義一個(gè)全局變量
int g_val= 100;
//新線程:
std::cout << threadname << " running ... : " << changeId(pthread_self()) 
		  <<" g_val: "<< g_val++ << " &g_val: " << &g_val << std::endl;
//主線程:
std::cout << "main thread running ... new thread id: " <<changeId(tid) 
          <<" main thread id: " << main_id << " g_val: "<< g_val << " &g_val: " << &g_val << std::endl;

我們在主線程與新線程都打印輸出g_val的值與地址:
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
我們可以發(fā)現(xiàn),主線程與新線程都是輸出同一個(gè)g_val值與地址,且這個(gè)地址非常小

添加__thread,可以將一個(gè)內(nèi)置類型設(shè)置為線程局部存儲(chǔ)

__thread int g_val = 100;

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
我們可以發(fā)現(xiàn),給g_val添加__thread后,主線程與新線程打印輸出的地址不一樣了,新線程對g_val的值進(jìn)行修改,主線程打印的值沒有變化。

原因圖:
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
一開始g_val已初始化數(shù)據(jù)段,添加__thread以后,使其設(shè)置為線程局部存儲(chǔ),每個(gè)線程都有一份且是在共享區(qū),已初始化數(shù)據(jù)段→共享區(qū)(地址由低到高),且它們訪問不會(huì)互相影響。


分離線程

  • 默認(rèn)情況下,新創(chuàng)建的線程是joinable的,線程退出后,需要對其進(jìn)行pthread_join操作,否則無法釋放資源,從而造成系統(tǒng)泄漏。
  • 如果不關(guān)心線程的返回值,join是一種負(fù)擔(dān),這個(gè)時(shí)候,我們可以告訴系統(tǒng),當(dāng)線程退出時(shí),自動(dòng)釋放線程資源。
  • 如果線程設(shè)置了分離狀態(tài),那么就不能join等待了。

分離一個(gè)線程:
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
函數(shù)原型:

int pthread_detach(pthread_t thread);

可以是線程組內(nèi)其他線程對目標(biāo)線程進(jìn)行分離,也可以是線程自己分離

驗(yàn)證分離以后不能join(里面有小bug,請思考):

#include <iostream>
#include <string>
#include <pthread.h>
#include <cstring>
#include <unistd.h>
std::string changeId(const pthread_t &thread_id)
{
    char tid[128];
    snprintf(tid, sizeof(tid), "0x%x", thread_id);
    return tid;
}
void *start_routine(void *args)
{
    std::string threadname = static_cast<const char *>(args);
    // pthread_detach(pthread_self());
    int cnt = 5;
    while (cnt--)
    {
        std::cout << threadname << " running ... : " << changeId(pthread_self()) << std::endl;
        sleep(1);
    }
    return nullptr;
}
int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, start_routine, (void *)"thread 1");
    std::string main_id = changeId(pthread_self());
    std::cout << "main thread running ... new thread id: " << changeId(tid) <<" main thread id: " << main_id << std::endl;
    int n = pthread_join(tid,nullptr);
    std::cout << "result : " << n << " : " << strerror(n) <<std::endl;
    return 0;
}

1.我們在start_routine里面沒有使用線程分離:
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
2.我們在start_routine里面使用線程分離pthread_detach
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
思考:為什么我在start_routine里面使用線程分離pthread_detach然后pthread_join還是成功了?
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
原因:由于主線程創(chuàng)建新線程以后,到底是主線程先運(yùn)行還是新線程先運(yùn)行是隨機(jī)的,如果主線程先運(yùn)行了pthread_join使得其已經(jīng)阻塞式等待了,然后新線程才pthread_detach分離,這個(gè)時(shí)候已經(jīng)晚了。
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器

當(dāng)然這種分離方式我們不贊成,我們一般這樣使用線程分離:

std::string changeId(const pthread_t &thread_id)
{
    char tid[128];
    snprintf(tid, sizeof(tid), "0x%x", thread_id);
    return tid;
}
void *start_routine(void *args)
{
    std::string threadname = static_cast<const char *>(args);
    int cnt = 5;
    while (cnt--)
    {
        std::cout << threadname << " running ... : " << changeId(pthread_self()) << std::endl;
        sleep(1);
    }
    return nullptr;
}
int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, start_routine, (void *)"thread 1");
    std::string main_id = changeId(pthread_self());
    pthread_detach(tid);//線程分離

    std::cout << "main thread running ... new thread id: " << changeId(tid) << " main thread id: " << main_id << std::endl;

    // int n = pthread_join(tid,nullptr);
    // std::cout << "result : " << n << " : " << strerror(n) <<std::endl;
    while (true)
    {
        std::cout << "main thread running ... " << std::endl;
    }
    return 0;
}

【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器
【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局,Linux基礎(chǔ),linux,線程控制,線程等待,線程分離,運(yùn)維,服務(wù)器


如有錯(cuò)誤或者不清楚的地方歡迎私信或者評論指出????文章來源地址http://www.zghlxwxcb.cn/news/detail-606661.html

到了這里,關(guān)于【Linux】詳解線程控制 -- 線程用法 | 線程等待 | 線程ID及地址空間布局的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • 【Linux-14】進(jìn)程地址空間&虛擬空間&頁表——原理&知識點(diǎn)詳解

    【Linux-14】進(jìn)程地址空間&虛擬空間&頁表——原理&知識點(diǎn)詳解

    前言 大家好吖,歡迎來到 YY 滴 系列 ,熱烈歡迎! 本章主要內(nèi)容面向接觸過Linux的老鐵 主要內(nèi)容含: 歡迎訂閱 YY 滴C++專欄!更多干貨持續(xù)更新!以下是傳送門! YY的《C++》專欄 YY的《C++11》專欄 YY的《Linux》專欄 YY的《數(shù)據(jù)結(jié)構(gòu)》專欄 YY的《C語言基礎(chǔ)》專欄 YY的《初學(xué)者易

    2024年04月29日
    瀏覽(31)
  • 『Linux』第九講:Linux多線程詳解(二)_ 線程控制

    『Linux』第九講:Linux多線程詳解(二)_ 線程控制

    「前言」文章是關(guān)于Linux多線程方面的知識,上一篇是 Linux多線程詳解(一),今天這篇是 Linux多線程詳解(二),講解會(huì)比較細(xì),下面開始! 「歸屬專欄」Linux系統(tǒng)編程 「主頁鏈接」個(gè)人主頁 「筆者」楓葉先生(fy) 「楓葉先生有點(diǎn)文青病」「每篇一句」 縱有千古,橫有八荒

    2024年02月01日
    瀏覽(18)
  • 多線程系列(六) -等待和通知模型詳解

    在之前的線程系列文章中,我們介紹了 synchronized 和 volatile ,使用它能解決線程同步的問題,但是它們無法解決線程之間協(xié)調(diào)和通信的問題。 舉個(gè)簡單的例子,比如線程 A 負(fù)責(zé)將 int 型變量 i 值累加操作到 10000,然后通知線程 B 負(fù)責(zé)把結(jié)果打印出來。 這個(gè)怎么實(shí)現(xiàn)呢?

    2024年02月22日
    瀏覽(23)
  • Linux - 進(jìn)程控制(下篇)- 進(jìn)程等待

    Linux - 進(jìn)程控制(下篇)- 進(jìn)程等待

    ?為什么進(jìn)程需要等待? ?我們知道,在Linux 當(dāng)中, 父子進(jìn)程之間一些結(jié)構(gòu) 就是一些 多叉樹 的結(jié)構(gòu),一個(gè)父進(jìn)程可能管理或者創(chuàng)建了很多個(gè)字進(jìn)程。 而其實(shí)我們在代碼當(dāng)中使用fork()函數(shù)創(chuàng)建的子進(jìn)程的父進(jìn)程,這個(gè)父進(jìn)程其實(shí)也是其他的父進(jìn)程的子進(jìn)程,我們在命令行

    2024年02月05日
    瀏覽(28)
  • Linux進(jìn)程控制【創(chuàng)建、終止、等待】

    Linux進(jìn)程控制【創(chuàng)建、終止、等待】

    ?個(gè)人主頁: Yohifo ??所屬專欄: Linux學(xué)習(xí)之旅 ??每篇一句: 圖片來源 ??操作環(huán)境: CentOS 7.6 阿里云遠(yuǎn)程服務(wù)器 Good judgment comes from experience, and a lot of that comes from bad judgment. 好的判斷力來自經(jīng)驗(yàn),其中很多來自糟糕的判斷力。 進(jìn)程 創(chuàng)建后,需要對其進(jìn)行合理管理,光靠

    2024年02月02日
    瀏覽(38)
  • 【Linux】進(jìn)程控制(創(chuàng)建、終止、等待)

    【Linux】進(jìn)程控制(創(chuàng)建、終止、等待)

    環(huán)境:centos7.6,騰訊云服務(wù)器 Linux文章都放在了專欄:【 Linux 】歡迎支持訂閱 相關(guān)文章推薦: 【Linux】馮.諾依曼體系結(jié)構(gòu)與操作系統(tǒng) 【Linux】進(jìn)程理解與學(xué)習(xí)Ⅰ-進(jìn)程概念 【Linux】進(jìn)程理解與學(xué)習(xí)Ⅱ-進(jìn)程狀態(tài) 【Linux】進(jìn)程理解與學(xué)習(xí)Ⅲ-環(huán)境變量 【Linux】進(jìn)程理解與學(xué)習(xí)Ⅳ

    2023年04月16日
    瀏覽(19)
  • 【linux進(jìn)程控制(二)】進(jìn)程等待--父進(jìn)程是如何等待子進(jìn)程死亡的?

    【linux進(jìn)程控制(二)】進(jìn)程等待--父進(jìn)程是如何等待子進(jìn)程死亡的?

    ??博主CSDN主頁:杭電碼農(nóng)-NEO?? ? ?專欄分類:Linux從入門到精通? ? ??代碼倉庫:NEO的學(xué)習(xí)日記?? ? ??關(guān)注我??帶你學(xué)更多操作系統(tǒng)知識 ? ???? ) 控制一個(gè)進(jìn)程包括如何創(chuàng)建它,如何 終止它,并且如何回收它的資源! 本章重點(diǎn): 本篇文章著重講解進(jìn)程等待的必要性 ,以及

    2024年02月05日
    瀏覽(22)
  • linux入門之進(jìn)程控制(上)進(jìn)程創(chuàng)建,進(jìn)程等待

    linux入門之進(jìn)程控制(上)進(jìn)程創(chuàng)建,進(jìn)程等待

    目錄 一、進(jìn)程創(chuàng)建 1.fork函數(shù) 2.fork函數(shù)返回值 3.寫時(shí)拷貝 4.fork常規(guī)用法 5.fork調(diào)用失敗原因 二、進(jìn)程終止 1.進(jìn)程退出場景 2.進(jìn)程常見退出方法 2.1_exit函數(shù)(直接調(diào)用內(nèi)核) 2.2 exit函數(shù) 2.3return退出 三、進(jìn)程等待 1.進(jìn)程等待必要性 2.進(jìn)程等待方法 2.1 wait方法 2.2 waitpid方法 2.3獲取

    2024年02月12日
    瀏覽(21)
  • 【當(dāng)前全網(wǎng)最詳細(xì)】WebUI中使用Instant_ID來控制生成對象面部的用法

    【當(dāng)前全網(wǎng)最詳細(xì)】WebUI中使用Instant_ID來控制生成對象面部的用法

    中文網(wǎng)絡(luò)上或者B站很多UP,在講述WebUI中使用這個(gè)controlnet來換臉的時(shí)候,要么講的過于復(fù)雜,要么就是沒有講清楚,所以這里整理下詳細(xì)的使用方法,并記錄下生成的內(nèi)容。 ?如果懶得看文字可以看同款視頻哈: 【AI寫真Instant_ID全網(wǎng)最詳細(xì)教程Stable Diffusion WebUI免費(fèi)生產(chǎn)力】

    2024年03月21日
    瀏覽(24)
  • 【Linux進(jìn)程控制】進(jìn)程創(chuàng)建 | 進(jìn)程終止 | 進(jìn)程等待 | 進(jìn)程替換

    【Linux進(jìn)程控制】進(jìn)程創(chuàng)建 | 進(jìn)程終止 | 進(jìn)程等待 | 進(jìn)程替換

    【寫在前面】 本文主要學(xué)習(xí)理解 fork 的返回值、寫時(shí)拷貝的工作細(xì)節(jié)、為什么要存在寫時(shí)拷貝;進(jìn)程退出碼、進(jìn)程退出的場景及常見的退出方法、對比 man 2 _exit 和 man 3 exit;進(jìn)程終止、操作系統(tǒng)怎么進(jìn)行釋放資源、池的概念;進(jìn)程等待的價(jià)值、進(jìn)程等待的方法 wait 和 waitpid

    2023年04月08日
    瀏覽(19)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包