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

【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程)

這篇具有很好參考價(jià)值的文章主要介紹了【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程),Linux,linux,java,數(shù)據(jù)庫,c++,c語言

引言

在當(dāng)今信息技術(shù)日新月異的時(shí)代,多線程編程已經(jīng)成為了日常開發(fā)中不可或缺的一部分。Linux作為一種廣泛應(yīng)用的操作系統(tǒng),其對(duì)多線程編程的支持也相當(dāng)完善。本文將會(huì)介紹關(guān)于Linux多線程相關(guān)的知識(shí),其中包括了線程的概念、線程控制、線程分離等方面的內(nèi)容。如果你希望提升自己的多線程編程能力,本文將為你提供實(shí)用的技術(shù)指導(dǎo)和詳盡的知識(shí)儲(chǔ)備。讓我們一起來深入了解Linux多線程編程的奧秘吧!

一、 Linux線程概念

1. 什么是線程

  • 在一個(gè)程序里的一個(gè)執(zhí)行路線就叫做線程(thread)。更準(zhǔn)確的定義是:線程是“一個(gè)進(jìn)程內(nèi)部的控制序列”。
  • 一切進(jìn)程至少都有一個(gè)執(zhí)行線程。
  • 線程在進(jìn)程內(nèi)部運(yùn)行,本質(zhì)是在進(jìn)程地址空間內(nèi)運(yùn)行。
  • 在Linux系統(tǒng)中,在CPU眼中,看到的PCB都要比傳統(tǒng)的進(jìn)程更加輕量化。
  • 透過進(jìn)程虛擬地址空間,可以看到進(jìn)程的大部分資源,將進(jìn)程資源合理分配給每個(gè)執(zhí)行流,就形成了線程執(zhí)行流。

2. 線程的概念

在Linux中,線程是指在同一個(gè)進(jìn)程內(nèi)部并發(fā)執(zhí)行的多個(gè)子任務(wù)。Linux將線程作為輕量級(jí)進(jìn)程(LWP)來實(shí)現(xiàn),每個(gè)線程共享相同的進(jìn)程地址空間和其他資源,包括文件描述符、信號(hào)處理器和其他內(nèi)核狀態(tài)。由于線程之間共享進(jìn)程的資源,因此線程之間的切換開銷通常比進(jìn)程之間的切換要小得多。

Linux使用POSIX線程庫(pthread)來支持多線程編程。通過pthread庫,開發(fā)人員可以方便地創(chuàng)建、控制和同步線程,實(shí)現(xiàn)多線程編程的各種功能。在Linux中,線程的創(chuàng)建和管理都是通過系統(tǒng)調(diào)用和pthread庫來完成的,開發(fā)人員可以使用pthread_create()函數(shù)創(chuàng)建新線程,并使用pthread_join()函數(shù)等來等待線程的結(jié)束,后面我們會(huì)詳細(xì)介紹。

在Linux中,線程與進(jìn)程一樣擁有自己的ID、寄存器上下文、棧和線程本地存儲(chǔ)(TLS)。線程可以通過共享內(nèi)存進(jìn)行通信,也可以使用線程同步機(jī)制來協(xié)調(diào)彼此的操作。在多核處理器上,Linux內(nèi)核會(huì)將不同的線程分配到不同的處理器核心上并行執(zhí)行,以提高系統(tǒng)的性能和響應(yīng)速度。

總的來說,Linux線程是在同一個(gè)進(jìn)程內(nèi)并發(fā)執(zhí)行的多個(gè)子任務(wù),通過共享進(jìn)程的資源和使用pthread庫來實(shí)現(xiàn)線程的創(chuàng)建和管理。在Linux環(huán)境下,充分利用線程可以提高程序的并發(fā)能力和性能表現(xiàn)。
【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程),Linux,linux,java,數(shù)據(jù)庫,c++,c語言

3. 線程與進(jìn)程的區(qū)別

Linux線程和進(jìn)程的主要區(qū)別在于它們是操作系統(tǒng)對(duì)應(yīng)不同的執(zhí)行單元。

  1. 資源分配

    • 進(jìn)程是資源分配的最小單位,每個(gè)進(jìn)程都有自己的地址空間、全局變量、堆棧、文件描述符等系統(tǒng)資源。
    • 線程是CPU調(diào)度的最小單位,多個(gè)線程可以共享同一個(gè)進(jìn)程的資源,包括地址空間、全局變量、文件描述符等。
  2. 切換開銷

    • 因?yàn)榫€程共享進(jìn)程資源,因此線程之間的切換開銷比進(jìn)程之間的切換要小得多。
    • 線程的上下文切換只需要保存處理器寄存器和棧指針,而進(jìn)程切換需要保存整個(gè)進(jìn)程的上下文信息,包括內(nèi)存映像、堆棧、寄存器等。
  3. 通信機(jī)制

    • 進(jìn)程之間通常使用IPC(Inter-Process Communication)機(jī)制來進(jìn)行進(jìn)程間通信,例如管道、消息隊(duì)列、共享內(nèi)存和信號(hào)量等。
    • 線程之間可以通過共享內(nèi)存、互斥鎖、條件變量等同步機(jī)制來進(jìn)行通信和協(xié)調(diào)。
  4. 并發(fā)能力

    • 由于線程共享進(jìn)程資源和較小的切換開銷,因此線程可以更輕松地實(shí)現(xiàn)并發(fā)執(zhí)行,提高程序的并發(fā)處理能力和性能表現(xiàn)。
  5. 安全性

    • 線程共享進(jìn)程資源,因此線程之間操作共享數(shù)據(jù)可能會(huì)引起競(jìng)態(tài)條件等并發(fā)問題,需要使用同步機(jī)制來協(xié)調(diào)線程的操作。
    • 進(jìn)程之間不共享地址空間,可以通過IPC機(jī)制來實(shí)現(xiàn)安全的進(jìn)程間通信。

?進(jìn)程和線程的關(guān)系如下圖
【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程),Linux,linux,java,數(shù)據(jù)庫,c++,c語言

4. 線程異常

  1. 線程死鎖:線程之間相互等待對(duì)方釋放資源,導(dǎo)致所有線程都無法繼續(xù)執(zhí)行的情況。

  2. 競(jìng)態(tài)條件:多個(gè)線程同時(shí)訪問共享的資源,導(dǎo)致意外的結(jié)果或者數(shù)據(jù)損壞。

  3. 內(nèi)存泄漏:線程未正確釋放動(dòng)態(tài)分配的內(nèi)存,導(dǎo)致系統(tǒng)資源耗盡。

  4. 線程間通信問題:線程之間的通信出現(xiàn)問題,例如數(shù)據(jù)丟失、阻塞等情況。

  5. 未捕獲的異常:線程中的代碼拋出未捕獲的異常,導(dǎo)致線程意外終止。

?當(dāng)一個(gè)線程出現(xiàn)嚴(yán)重的異常導(dǎo)致崩潰時(shí),會(huì)觸發(fā)進(jìn)程內(nèi)的異常處理機(jī)制。在大多數(shù)操作系統(tǒng)中,異常會(huì)導(dǎo)致信號(hào)被發(fā)送給進(jìn)程,例如SIGSEGV(段錯(cuò)誤)或SIGFPE(浮點(diǎn)異常)。默認(rèn)情況下,這些信號(hào)會(huì)終止整個(gè)進(jìn)程。

??注意線程是進(jìn)程的執(zhí)行分支,線程出異常,就類似進(jìn)程出異常,進(jìn)而觸發(fā)信號(hào)機(jī)制,終止進(jìn)程,進(jìn)程終止,該進(jìn)程內(nèi)的所有線程也就隨即退出

二、Linux線程控制

1. POSIX線程庫

在Linux系統(tǒng)中,POSIX線程庫(也稱為pthread庫)是一套用于多線程編程的標(biāo)準(zhǔn)接口。它基于POSIX標(biāo)準(zhǔn)(Portable Operating System Interface)定義了一組函數(shù)和數(shù)據(jù)類型,使得開發(fā)者可以方便地進(jìn)行多線程程序的開發(fā)。

POSIX線程庫的設(shè)計(jì)目標(biāo)是提供一個(gè)可移植、高效和可靠的多線程編程接口。它已經(jīng)成為類UNIX系統(tǒng)上標(biāo)準(zhǔn)的多線程編程接口,并在Linux系統(tǒng)中得到廣泛應(yīng)用。開發(fā)者可以使用POSIX線程庫編寫具有良好可移植性的多線程程序,無需關(guān)心底層操作系統(tǒng)的差異

2. 創(chuàng)建線程 pthread_create() 函數(shù)

在Linux系統(tǒng)中,線程的創(chuàng)建是通過POSIX線程庫(pthread庫)提供的函數(shù)來實(shí)現(xiàn)的

(1)頭文件

pthread_create() 函數(shù)的使用需要包含pthread庫的頭文件pthread.h

#include <pthread.h>

(2)函數(shù)原型

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

(3)參數(shù)解釋

  1. thread:指向 pthread_t 類型的指針,用于存儲(chǔ)新線程的標(biāo)識(shí)符。在函數(shù)成功返回時(shí),該指針被設(shè)置為新線程的標(biāo)識(shí)符,可以用于后續(xù)操作。

  2. attr:指向 pthread_attr_t 類型的指針,用于設(shè)置線程的屬性,通??梢詡魅?nullptr,表示使用默認(rèn)屬性。如果需要設(shè)置線程的屬性,可以使用 pthread_attr_init() 函數(shù)初始化屬性對(duì)象,并使用 pthread_attr_setxxx() 函數(shù)設(shè)置屬性。

  3. start_routine:指向線程函數(shù)的指針,即新線程的執(zhí)行體。該函數(shù)應(yīng)該以 void* func(void*) 的形式定義,即帶有一個(gè) void 類型指針參數(shù),返回一個(gè) void 類型指針。線程函數(shù)的返回值將作為線程的退出狀態(tài),可以通過 pthread_join() 函數(shù)獲取。

  4. arg:傳遞給線程函數(shù)的參數(shù),它必須是一個(gè) void 類型指針,開發(fā)者需要自行處理類型轉(zhuǎn)換。

(4)返回值

  • 如果成功創(chuàng)建了新線程,則函數(shù)返回 0;
  • 如果失敗,則返回一個(gè)非零值,表示出現(xiàn)了錯(cuò)誤。在出錯(cuò)的情況下,可以使用 perror() 函數(shù)輸出錯(cuò)誤信息,也可以使用 strerror() 函數(shù)獲取錯(cuò)誤信息。

(5)使用示例

#include <stdio.h>
#include <pthread.h>

void* thread_function(void* arg) {
    int tid = *(int*)arg;
    printf("This is thread %d.\n", tid);
    pthread_exit(NULL);
}

int main() {
    pthread_t tid[3];
    int i, rc;

    // 創(chuàng)建三個(gè)新線程
    for (i = 0; i < 3; i++) {
        rc = pthread_create(&tid[i], NULL, thread_function, (void*)&i);
        if (rc != 0) {
            fprintf(stderr, "Failed to create new thread.\n");
            return 1;
        }
    }

    // 等待所有新線程結(jié)束
    for (i = 0; i < 3; i++) {
        rc = pthread_join(tid[i], NULL);
        if (rc != 0) {
            fprintf(stderr, "Failed to join the thread.\n");
            return 1;
        }
    }

    printf("All threads exit.\n");
    return 0;
}

通過上面的步驟,可以在 Linux 系統(tǒng)下成功創(chuàng)建并執(zhí)行新的線程。需要注意的是,調(diào)pthread_create() 函數(shù)時(shí)傳遞給線程函數(shù)的參數(shù)必須是指向整型變量的指針,否則可能會(huì)出現(xiàn)不可預(yù)期的錯(cuò)誤。

【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程),Linux,linux,java,數(shù)據(jù)庫,c++,c語言

3. 線程ID及進(jìn)程地址空間布局

(1)進(jìn)程地址空間布局

進(jìn)程地址空間布局是指操作系統(tǒng)在內(nèi)存中為每個(gè)進(jìn)程分配的地址空間的布局方式。以下是典型的Linux進(jìn)程地址空間布局:

  1. 代碼段(Text Segment):
    代碼段存儲(chǔ)了可執(zhí)行程序的機(jī)器指令。它通常是只讀的,并且在內(nèi)存中只有一份,用于所有執(zhí)行該程序的進(jìn)程。

  2. 數(shù)據(jù)段(Data Segment):
    數(shù)據(jù)段存儲(chǔ)了全局變量和靜態(tài)變量。它包括了初始化的數(shù)據(jù)和非初始化的BSS段(Block Started by Symbol)。數(shù)據(jù)段通常是可讀寫的。

  3. 堆(Heap):
    堆是動(dòng)態(tài)分配內(nèi)存的區(qū)域。在運(yùn)行時(shí),通過調(diào)用malloc()、calloc()等函數(shù)分配堆內(nèi)存。堆的大小不固定,可以根據(jù)需要?jiǎng)討B(tài)增長(zhǎng)或縮小。

  4. 棧(Stack):
    棧用于存儲(chǔ)函數(shù)調(diào)用、局部變量和函數(shù)參數(shù)等信息。每個(gè)線程都有自己的棧,用于保存線程特定的上下文信息。棧的大小通常是固定的。

  5. 共享庫(Shared Libraries):
    共享庫存儲(chǔ)了被多個(gè)進(jìn)程共享的代碼和數(shù)據(jù)。它們被加載到內(nèi)存中,并映射到每個(gè)進(jìn)程的地址空間中。

  6. 內(nèi)核空間(Kernel Space):
    內(nèi)核空間是由操作系統(tǒng)內(nèi)核使用的內(nèi)存區(qū)域,不屬于進(jìn)程的地址空間。它包括操作系統(tǒng)內(nèi)核的代碼和數(shù)據(jù)結(jié)構(gòu)。

【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程),Linux,linux,java,數(shù)據(jù)庫,c++,c語言

(2)線程ID pthread_self() 函數(shù)

線程ID(Thread ID)是操作系統(tǒng)分配給每個(gè)線程的唯一標(biāo)識(shí)符。在不同的操作系統(tǒng)中,線程ID的表示方式和取值范圍可能會(huì)有所不同。
pthread_self()函數(shù)是一個(gè)POSIX線程庫中的函數(shù),用于獲取當(dāng)前線程的線程ID。它的原型如下:

pthread_t pthread_self(void);

該函數(shù)沒有參數(shù),返回類型為pthread_t,即線程ID的類型。

使用pthread_self()函數(shù)可以在多線程程序中獲取當(dāng)前線程的線程ID。每個(gè)線程在創(chuàng)建時(shí)都會(huì)被分配一個(gè)唯一的線程ID,可以通過該ID來標(biāo)識(shí)和區(qū)分不同的線程。

下面是一個(gè)簡(jiǎn)單的示例代碼,演示了如何使用pthread_self()函數(shù)獲取當(dāng)前線程的線程ID:

#include <stdio.h>
#include <pthread.h>

void* thread_func(void* arg) {
    pthread_t tid = pthread_self();
    printf("Thread ID: %lu\n", tid);
    return NULL;
}

int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, thread_func, NULL);
    pthread_join(tid, NULL);
    return 0;
}

在上述示例中,主線程創(chuàng)建了一個(gè)新線程,并通過pthread_create()函數(shù)啟動(dòng)線程執(zhí)行thread_func()函數(shù)。在thread_func()函數(shù)中,調(diào)用pthread_self()函數(shù)獲取當(dāng)前線程的線程ID,并將其打印輸出。

??注意線程ID的類型pthread_t可能是一個(gè)不透明的數(shù)據(jù)類型,具體實(shí)現(xiàn)取決于操作系統(tǒng)和編譯器。在上述示例中,使用%lu格式指定符打印無符號(hào)長(zhǎng)整型,以與pthread_t類型匹配。在不同的系統(tǒng)和編譯環(huán)境中,可能需要根據(jù)具體情況調(diào)整打印格式。
【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程),Linux,linux,java,數(shù)據(jù)庫,c++,c語言

4. 線程等待 pthread_join() 函數(shù)

?線程等待是一種同步機(jī)制,會(huì)導(dǎo)致線程之間的阻塞和等待。在設(shè)計(jì)多線程程序時(shí),需要合理地安排線程的執(zhí)行順序和等待關(guān)系,以避免死鎖、饑餓等問題。pthread_join()函數(shù)是一個(gè)POSIX線程庫中的函數(shù),用于等待指定的線程結(jié)束并回收其資源。

(1)頭文件

pthread_join() 函數(shù)的使用需要包含pthread庫的頭文件pthread.h

#include <pthread.h>

(2)函數(shù)原型

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

(3)參數(shù)解釋

  • thread參數(shù)是要等待的目標(biāo)線程的線程ID,
  • retval參數(shù)用于接收目標(biāo)線程的返回值(如果有)。pthread_join()函數(shù)會(huì)阻塞調(diào)用線程,直到目標(biāo)線程結(jié)束為止,并且可以獲取目標(biāo)線程的返回值

(4)返回值

pthread_join() 函數(shù)的返回值表示線程的終止?fàn)顟B(tài),具體取值如下:

  • 如果線程的返回值已經(jīng)被存放到 value_ptr 指向的內(nèi)存中,則返回 0。
  • 如果指定的線程在執(zhí)行過程中被取消,則返回 PTHREAD_CANCELED。
  • 如果調(diào)用該函數(shù)時(shí)出現(xiàn)錯(cuò)誤,則返回相應(yīng)的錯(cuò)誤代碼。

(5)使用示例

下面是一個(gè)簡(jiǎn)單的示例代碼,演示了如何使用pthread_join()函數(shù)等待子線程結(jié)束并獲取其返回值:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void* thread_func(void* arg) {
    int* result = (int*)malloc(sizeof(int));
    *result = 42;
    printf("Thread is about to exit\n");
    pthread_exit((void*)result);  // 終止線程,并返回 result
}

int main() {
    pthread_t tid;
    void* ret_val;

    pthread_create(&tid, NULL, thread_func, NULL);
    pthread_join(tid, &ret_val);  // 獲取線程的返回值

    if (ret_val) {
        printf("Thread returned: %d\n", *((int*)ret_val));
        free(ret_val);  // 釋放返回值對(duì)應(yīng)的內(nèi)存
    } else {
        printf("Thread returned NULL\n");
    }

    return 0;
}

在上面的示例中,我們創(chuàng)建了一個(gè)新線程,線程函數(shù)中使用了 pthread_exit() 函數(shù)來結(jié)束線程并返回一個(gè)整數(shù)值。在主線程中,我們通過 pthread_join() 函數(shù)等待線程的終止,并獲取了線程的返回值。

??注意pthread_join()函數(shù)會(huì)使調(diào)用線程進(jìn)入阻塞狀態(tài),直到目標(biāo)線程結(jié)束。如果不關(guān)心目標(biāo)線程的返回值,也可以將retval參數(shù)設(shè)置為NULL。另外,在多線程程序中,需要特別注意線程的安全退出和資源回收,以避免產(chǎn)生懸掛線程或資源泄漏的問題。
【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程),Linux,linux,java,數(shù)據(jù)庫,c++,c語言

5. 線程終止

(1)線程終止的三種方法

  1. 線程函數(shù)返回:線程函數(shù)執(zhí)行完畢并從函數(shù)中返回,線程會(huì)自動(dòng)終止。線程函數(shù)可以通過返回一個(gè)值來傳遞結(jié)果給線程的創(chuàng)建者。

  2. 調(diào)用 pthread_exit() 函數(shù):線程可以顯式地調(diào)用 pthread_exit() 函數(shù)來終止自己。這個(gè)函數(shù)接受一個(gè)參數(shù)作為線程的返回值,可以被其他線程通過調(diào)用 pthread_join() 函數(shù)獲取。

  3. 取消線程:線程可以被其他線程取消。調(diào)用 pthread_cancel(pthread_t thread) 函數(shù)可以請(qǐng)求取消指定的線程。被取消的線程可以選擇在適當(dāng)?shù)臅r(shí)機(jī)終止自己,或者忽略取消請(qǐng)求繼續(xù)執(zhí)行。

(2)pthread_exit() 函數(shù)

pthread_exit() 函數(shù)是用于終止當(dāng)前線程并返回一個(gè)值的 POSIX 線程庫函數(shù)。該函數(shù)的原型如下所示:

void pthread_exit(void* value_ptr);
  • value_ptr:表示線程的返回值,可以是任意類型的指針。當(dāng)線程調(diào)用 pthread_exit() 函數(shù)時(shí),會(huì)將 value_ptr 指向的內(nèi)容作為線程的返回值。

pthread_exit() 函數(shù)允許線程在執(zhí)行過程中隨時(shí)退出,并返回一個(gè)值。這個(gè)返回值可以被其他線程通過調(diào)用 pthread_join() 函數(shù)獲取,從而實(shí)現(xiàn)線程間的數(shù)據(jù)交互和結(jié)果傳遞。

下面是一個(gè)簡(jiǎn)單的示例,演示了如何在線程中使用 pthread_exit() 函數(shù)來結(jié)束線程并返回一個(gè)值:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void* thread_func(void* arg) {
    int* result = (int*)malloc(sizeof(int));
    *result = 42;
    printf("Thread is about to exit\n");
    pthread_exit((void*)result);  // 終止線程,并返回 result
}

int main() {
    pthread_t tid;
    void* ret_val;

    pthread_create(&tid, NULL, thread_func, NULL);
    pthread_join(tid, &ret_val);  // 獲取線程的返回值
    printf("Thread returned: %d\n", *((int*)ret_val));

    free(ret_val);  // 釋放返回值對(duì)應(yīng)的內(nèi)存
    return 0;
}

在上面的示例中,我們創(chuàng)建了一個(gè)新線程,線程函數(shù)中使用了 pthread_exit() 函數(shù)來結(jié)束線程并返回一個(gè)整數(shù)值。在主線程中,我們通過 pthread_join() 函數(shù)獲取了線程的返回值,并打印輸出了該值。

(3)pthread_cancel() 函數(shù)

pthread_cancel() 函數(shù)是 POSIX 線程庫中用于取消指定線程的函數(shù)。該函數(shù)的原型如下所示:

int pthread_cancel(pthread_t thread);
  • thread:表示要取消的線程的標(biāo)識(shí)符。

pthread_cancel() 函數(shù)會(huì)向指定線程發(fā)送一個(gè)取消請(qǐng)求,并嘗試終止該線程的執(zhí)行。但是,線程是否會(huì)被成功取消取決于多個(gè)因素,包括線程自身的取消狀態(tài)和取消點(diǎn)的設(shè)置。

pthread_cancel() 函數(shù)只是發(fā)送一個(gè)取消請(qǐng)求并立即返回,并不能保證目標(biāo)線程會(huì)立即終止。目標(biāo)線程可以選擇忽略取消請(qǐng)求或者在適當(dāng)?shù)娜∠c(diǎn)進(jìn)行處理。

取消點(diǎn)(cancellation point)是線程中的一些特定位置,線程在這些位置上可以檢查是否有取消請(qǐng)求,并決定是否終止自己的執(zhí)行。常見的取消點(diǎn)包括 I/O 操作、阻塞的系統(tǒng)調(diào)用等。

如果目標(biāo)線程成功響應(yīng)了取消請(qǐng)求,并在取消點(diǎn)終止了執(zhí)行,那么取消狀態(tài)將被設(shè)置為已取消。可以通過調(diào)用 pthread_setcancelstate()pthread_setcanceltype() 函數(shù)來控制線程的取消狀態(tài)和取消類型。

下面是一個(gè)示例,演示了如何使用 pthread_cancel() 函數(shù)來取消線程的執(zhí)行:

#include <stdio.h>
#include <pthread.h>

void* thread_func(void* arg) {
    while (1) {
        // 線程執(zhí)行的邏輯
    }
    return NULL;
}

int main() {
    pthread_t tid;

    pthread_create(&tid, NULL, thread_func, NULL);

    // 在主線程中取消子線程的執(zhí)行
    pthread_cancel(tid);

    pthread_join(tid, NULL);  // 等待線程結(jié)束

    return 0;
}

在上面的示例中,我們創(chuàng)建了一個(gè)新線程,并在主線程中調(diào)用 pthread_cancel() 函數(shù)來取消子線程的執(zhí)行。接著,我們使用 pthread_join() 函數(shù)等待子線程的終止。

??注意在使用 pthread_cancel() 函數(shù)取消線程時(shí),應(yīng)確保目標(biāo)線程處于可取消狀態(tài),并且在適當(dāng)?shù)奈恢迷O(shè)置了取消點(diǎn)。否則,取消請(qǐng)求可能被忽略,導(dǎo)致線程無法正確終止。

三、分離線程

1. joinable與線程分離

“joinable” 和線程分離是兩種不同的線程狀態(tài)。

  • “joinable” 狀態(tài)的線程是指可以被其他線程顯式等待和回收資源的線程。在 POSIX 線程庫中,默認(rèn)情況下,創(chuàng)建的線程是可連接狀態(tài)(joinable)??蛇B接狀態(tài)的線程需要使用 pthread_join() 函數(shù)來等待其終止,并獲取其返回值(如果有)。
  • 線程分離是指將線程屬性設(shè)置為分離狀態(tài),使得線程在終止時(shí)可以自動(dòng)釋放相關(guān)資源,而無需等待其他線程顯式對(duì)其進(jìn)行回收。分離線程通常用于不需要獲取線程返回值或進(jìn)行線程同步的場(chǎng)景。

2. 分離線程 pthread_detach() 函數(shù)

pthread_detach() 函數(shù)是 POSIX 線程庫中的一個(gè)函數(shù),用于將指定線程設(shè)置為分離狀態(tài),即使該線程在終止時(shí)可以自動(dòng)釋放相關(guān)資源,而無需等待其他線程顯式對(duì)其進(jìn)行回收。

(1)頭文件

pthread_detach() 函數(shù)的使用需要包含pthread庫的頭文件pthread.h

#include <pthread.h>

(2)函數(shù)原型

int pthread_detach(pthread_t thread);

(3)參數(shù)解釋

  • thread:表示要設(shè)置為分離狀態(tài)的線程的標(biāo)識(shí)符。

(4)返回值

pthread_detach() 函數(shù)的返回值為 0 表示調(diào)用成功,返回值為非零表示調(diào)用失敗。失敗的原因可能是參數(shù)不正確或者內(nèi)部出現(xiàn)了錯(cuò)誤。

??注意線程在被設(shè)置為分離狀態(tài)之前,必須處于可連接狀態(tài)。否則,pthread_detach() 函數(shù)將無法將其設(shè)置為分離狀態(tài),并返回一個(gè)錯(cuò)誤碼。

(5)使用示例

下面是一個(gè)示例,演示了如何使用 pthread_detach() 函數(shù)將線程設(shè)置為分離狀態(tài):

#include <stdio.h>
#include <pthread.h>

void* thread_func(void* arg) {
    // 線程執(zhí)行的邏輯
    return NULL;
}

int main() {
    pthread_t tid;

    pthread_create(&tid, NULL, thread_func, NULL);

    // 將線程設(shè)置為分離狀態(tài)
    pthread_detach(tid);

    // 不需要使用 pthread_join() 函數(shù)進(jìn)行回收

    return 0;
}

在上面的示例中,我們創(chuàng)建了一個(gè)新線程,并使用 pthread_detach() 函數(shù)將其設(shè)置為分離狀態(tài)。由于該線程已經(jīng)處于分離狀態(tài),因此在主線程中無需使用 pthread_join() 函數(shù)進(jìn)行回收。

四、線程的優(yōu)缺點(diǎn)

線程是一種輕量級(jí)的執(zhí)行單元,可以在一個(gè)進(jìn)程內(nèi)并發(fā)執(zhí)行多個(gè)任務(wù)。線程有以下優(yōu)點(diǎn)和缺點(diǎn):

?優(yōu)點(diǎn)

  1. 并發(fā)執(zhí)行:線程允許多個(gè)任務(wù)同時(shí)執(zhí)行,提高了程序的運(yùn)行效率和響應(yīng)速度??梢猿浞掷枚嗪颂幚砥鞯挠?jì)算能力。
  2. 共享數(shù)據(jù):線程可以共享同一個(gè)進(jìn)程的內(nèi)存空間,方便數(shù)據(jù)之間的共享和通信。不同線程之間可以直接讀取和修改同一塊內(nèi)存區(qū)域的數(shù)據(jù),簡(jiǎn)化了多任務(wù)編程的復(fù)雜性。
  3. 資源高效:線程的創(chuàng)建和銷毀消耗的資源相對(duì)較少,線程切換的開銷也較小。相比于進(jìn)程,線程更加輕量級(jí)。
  4. 邏輯清晰:使用線程可以將程序分解成多個(gè)獨(dú)立的執(zhí)行單元,每個(gè)線程負(fù)責(zé)不同的任務(wù),使得程序的邏輯結(jié)構(gòu)更加清晰、模塊化。

?缺點(diǎn)

  1. 同步和共享問題:多個(gè)線程訪問共享數(shù)據(jù)時(shí)需要進(jìn)行同步操作,以避免數(shù)據(jù)競(jìng)爭(zhēng)和不一致的結(jié)果。需要使用鎖、信號(hào)量等機(jī)制來保護(hù)共享資源,增加了編程的復(fù)雜性。
  2. 錯(cuò)誤管理困難:線程共享同一進(jìn)程的內(nèi)存空間,一個(gè)線程對(duì)共享資源的錯(cuò)誤操作可能會(huì)影響其他線程的正常執(zhí)行,導(dǎo)致難以追蹤和調(diào)試錯(cuò)誤。
  3. 調(diào)試和測(cè)試復(fù)雜:由于線程并發(fā)執(zhí)行,線程之間的交互和調(diào)試相對(duì)復(fù)雜。當(dāng)程序出現(xiàn)問題時(shí),需要仔細(xì)分析各個(gè)線程的執(zhí)行順序和交互情況,增加了調(diào)試和測(cè)試的難度。
  4. 資源競(jìng)爭(zhēng):多個(gè)線程同時(shí)訪問共享資源時(shí)可能引發(fā)資源競(jìng)爭(zhēng)問題,如死鎖、饑餓等。需要合理設(shè)計(jì)和管理線程的同步和互斥機(jī)制,以避免資源競(jìng)爭(zhēng)問題。

五、線程用途

  • 合理的使用多線程,能提高CPU密集型程序的執(zhí)行效率。
  • 合理的使用多線程,能提高IO密集型程序的用戶體驗(yàn)。(如生活中我們一邊寫代碼一邊下載開發(fā)工具,就是多線程運(yùn)行的一種表現(xiàn))

溫馨提示

感謝您對(duì)博主文章的關(guān)注與支持!如果您喜歡這篇文章,可以點(diǎn)贊、評(píng)論和分享給您的同學(xué),這將對(duì)我提供巨大的鼓勵(lì)和支持。另外,我計(jì)劃在未來的更新中持續(xù)探討與本文相關(guān)的內(nèi)容。我會(huì)為您帶來更多關(guān)于Linux以及C++編程技術(shù)問題的深入解析、應(yīng)用案例和趣味玩法等。如果感興趣的話可以關(guān)注博主的更新,不要錯(cuò)過任何精彩內(nèi)容!

再次感謝您的支持和關(guān)注。我們期待與您建立更緊密的互動(dòng),共同探索Linux、C++、算法和編程的奧秘。祝您生活愉快,排便順暢!
【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程),Linux,linux,java,數(shù)據(jù)庫,c++,c語言文章來源地址http://www.zghlxwxcb.cn/news/detail-753702.html

到了這里,關(guān)于【探索Linux】—— 強(qiáng)大的命令行工具 P.19(多線程 | 線程的概念 | 線程控制 | 分離線程)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

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

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

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

    2024年03月10日
    瀏覽(102)
  • 【探索Linux】—— 學(xué)習(xí)強(qiáng)大的命令行工具 P.1(Linux簡(jiǎn)介)

    【探索Linux】—— 學(xué)習(xí)強(qiáng)大的命令行工具 P.1(Linux簡(jiǎn)介)

    目錄 前言 一、Linux簡(jiǎn)介 二、linux的不同發(fā)行版本 三、Linux的開源性質(zhì) 四、Linux的特點(diǎn)? 五、Linux代碼演示(僅供參考)? 總結(jié) ? ? ? ? 前面我們講了C語言的基礎(chǔ)知識(shí),也了解了一些數(shù)據(jù)結(jié)構(gòu),并且講了有關(guān)C++的一些知識(shí),也相信大家都掌握的不錯(cuò),今天博主將會(huì)新開一個(gè)L

    2024年02月11日
    瀏覽(51)
  • 【探索Linux】—— 強(qiáng)大的命令行工具 P.3(Linux開發(fā)工具 vim)

    【探索Linux】—— 強(qiáng)大的命令行工具 P.3(Linux開發(fā)工具 vim)

    前面我們講了C語言的基礎(chǔ)知識(shí),也了解了一些數(shù)據(jù)結(jié)構(gòu),并且講了有關(guān)C++的一些知識(shí),也學(xué)習(xí)了一些Linux的基本操作,也相信大家都掌握的不錯(cuò),今天博主帶大家了解一下Linux開發(fā)工具—— vim ,下面話不多說坐穩(wěn)扶好咱們要開車了?。?!?? Vim(Vi IMproved)是一款在Unix和類

    2024年02月12日
    瀏覽(54)
  • 【探索Linux】—— 步步學(xué)習(xí)強(qiáng)大的命令行工具 P.1(Linux簡(jiǎn)介)

    【探索Linux】—— 步步學(xué)習(xí)強(qiáng)大的命令行工具 P.1(Linux簡(jiǎn)介)

    目錄 前言 一、Linux簡(jiǎn)介 二、linux的不同發(fā)行版本 三、Linux的開源性質(zhì) 四、Linux的特點(diǎn)? 五、Linux代碼演示(僅供參考)? 總結(jié) ? ? ? ? 前面我們講了C語言的基礎(chǔ)知識(shí),也了解了一些數(shù)據(jù)結(jié)構(gòu),并且講了有關(guān)C++的一些知識(shí),也相信大家都掌握的不錯(cuò),今天博主將會(huì)新開一個(gè)L

    2024年02月14日
    瀏覽(22)
  • 【linux】探索Linux命令行中強(qiáng)大的網(wǎng)絡(luò)工具:netstat

    【linux】探索Linux命令行中強(qiáng)大的網(wǎng)絡(luò)工具:netstat

    在Linux命令行中,有許多實(shí)用的工具可幫助我們管理和監(jiān)控網(wǎng)絡(luò)連接。其中一個(gè)最重要的工具就是netstat,它提供了豐富的網(wǎng)絡(luò)連接和統(tǒng)計(jì)信息,幫助我們?cè)\斷網(wǎng)絡(luò)問題并了解系統(tǒng)的網(wǎng)絡(luò)狀態(tài)。 在日常的網(wǎng)絡(luò)管理和故障排除過程中,了解系統(tǒng)的網(wǎng)絡(luò)連接情況是至關(guān)重要的。而在

    2024年02月09日
    瀏覽(38)
  • 【探索Linux】—— 強(qiáng)大的命令行工具 P.2(Linux下基本指令)

    【探索Linux】—— 強(qiáng)大的命令行工具 P.2(Linux下基本指令)

    ? ? ? ? 前面我們講了C語言的基礎(chǔ)知識(shí),也了解了一些數(shù)據(jù)結(jié)構(gòu),并且講了有關(guān)C++的一些知識(shí),也相信大家都掌握的不錯(cuò),今天博主將會(huì)新開一個(gè)Linux專題,帶領(lǐng)大家繼續(xù)學(xué)習(xí)有關(guān)Linux的內(nèi)容。今天第一篇文章博主首先帶領(lǐng)大家了解一下什么是Linux,以及Linux的幾個(gè)常用命令符

    2024年02月14日
    瀏覽(22)
  • 【探索Linux】—— 強(qiáng)大的命令行工具 P.5(yum工具、git 命令行提交代碼)

    【探索Linux】—— 強(qiáng)大的命令行工具 P.5(yum工具、git 命令行提交代碼)

    前面我們講了C語言的基礎(chǔ)知識(shí),也了解了一些數(shù)據(jù)結(jié)構(gòu),并且講了有關(guān)C++的一些知識(shí),也學(xué)習(xí)了一些Linux的基本操作,也了解并學(xué)習(xí)了有關(guān)Linux開發(fā)工具vim 、gcc/g++ 使用,也相信大家都掌握的不錯(cuò),今天博主帶大家了解一下 —— yum工具以及git 命令行提交代碼 , 下面話不多說

    2024年02月12日
    瀏覽(25)
  • 【探索Linux】—— 強(qiáng)大的命令行工具 P.9(進(jìn)程地址空間)

    【探索Linux】—— 強(qiáng)大的命令行工具 P.9(進(jìn)程地址空間)

    前面我們講了C語言的基礎(chǔ)知識(shí),也了解了一些數(shù)據(jù)結(jié)構(gòu),并且講了有關(guān)C++的一些知識(shí),也學(xué)習(xí)了一些Linux的基本操作,也了解并學(xué)習(xí)了有關(guān)Linux開發(fā)工具vim 、gcc/g++ 使用、yum工具以及git 命令行提交代碼也相信大家都掌握的不錯(cuò),上一篇文章我們了解了關(guān)于進(jìn)程的基本概念,今

    2024年02月08日
    瀏覽(28)
  • 【探索Linux】—— 強(qiáng)大的命令行工具 P.22(POSIX信號(hào)量)

    【探索Linux】—— 強(qiáng)大的命令行工具 P.22(POSIX信號(hào)量)

    在上一篇文章中,我們深入探討了多線程編程的核心概念,包括線程同步、條件變量以及線程安全等關(guān)鍵技術(shù),為讀者揭示了并發(fā)編程的復(fù)雜性及其解決方案。這些概念和技術(shù)是實(shí)現(xiàn)高效、穩(wěn)定并發(fā)應(yīng)用程序的基礎(chǔ)。繼續(xù)在并發(fā)編程的旅途上前進(jìn),本篇文章將引導(dǎo)我們走進(jìn)

    2024年02月20日
    瀏覽(27)
  • 【探索Linux】—— 強(qiáng)大的命令行工具 P.11(基礎(chǔ)IO,文件操作)

    【探索Linux】—— 強(qiáng)大的命令行工具 P.11(基礎(chǔ)IO,文件操作)

    前面我們講了C語言的基礎(chǔ)知識(shí),也了解了一些數(shù)據(jù)結(jié)構(gòu),并且講了有關(guān)C++的一些知識(shí),也學(xué)習(xí)了一些Linux的基本操作,也了解并學(xué)習(xí)了有關(guān)Linux開發(fā)工具vim 、gcc/g++ 使用、yum工具以及git 命令行提交代碼也相信大家都掌握的不錯(cuò),上一篇文章我們了解了關(guān)于進(jìn)程的地址空間,今

    2024年02月08日
    瀏覽(18)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包