最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux線(xiàn)程之線(xiàn)程的創(chuàng)建、屬性、回收、退出、取消方式

 更新時(shí)間:2025年07月11日 14:32:40   作者:偉大的馬師兄  
文章總結(jié)了線(xiàn)程管理核心知識(shí):線(xiàn)程號(hào)唯一、創(chuàng)建方式、屬性設(shè)置(如分離狀態(tài)與棧大?。?、回收機(jī)制(join/detach)、退出方法(返回/pthread_exit/取消)及注意事項(xiàng),如避免僵尸線(xiàn)程、內(nèi)存釋放、信號(hào)機(jī)制使用限制等

1. 線(xiàn)程號(hào)

進(jìn)程號(hào)在系統(tǒng)中唯一,但線(xiàn)程號(hào)只在其所屬進(jìn)程環(huán)境中有效。

(1)pthread_self函數(shù)

#include<pthread.h>

pthread_t pthread_self(void);
/*
功能:
    獲取線(xiàn)程號(hào)
返回值:
    調(diào)用此函數(shù)線(xiàn)程的ID
*/

pthread_self示例:

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

int main(int argc, const char* argv[]) {
    pthread_t tid = 0;
    tid = pthread_self();
    printf("當(dāng)前線(xiàn)程id:%lu.\n", tid);
    return 0;
}

編譯時(shí)需要加上-pthread鏈接到pthread庫(kù)

運(yùn)行結(jié)果:

(2)pthread_equal函數(shù)

int pthraed_equal(pthread_t t1, pthread_t t2);
/*
功能:
    判斷線(xiàn)程號(hào)t1、t2是否相等。
返回值:
    相等:非0
    不等:0
*/

pthread_equal示例:

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

int main(int argc, const char* argv[]) {
    pthread_t tid = 0;
    tid = pthread_self();

    if (pthread_equal(tid, pthread_self())) {
        printf("線(xiàn)程id相等.\n");
    } else {
        printf("線(xiàn)程id不等.\n");
    }
    return 0;
}

運(yùn)行結(jié)果:

2. 線(xiàn)程的創(chuàng)建

pthread_create函數(shù)

#include<pthread.h>

int pthread_create(pthread_t* thread, const pthread_attr_t* attr, 
                    void* (*start_coutine)(void*), void* arg);
/*
功能:
    創(chuàng)建一個(gè)線(xiàn)程。
參數(shù):
    thread:線(xiàn)程id地址,為傳出參數(shù);
    attr:線(xiàn)程屬性結(jié)構(gòu)體,通常設(shè)置為NULL;
    start_routine:線(xiàn)程函數(shù)入口地址
    arg:傳給線(xiàn)程函數(shù)的參數(shù);
返回值:
    成功:0
    失?。悍?,未設(shè)置errno,不可使用perror。
*/

pthread_create示例:

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

void* threadFunc(void* arg) { // 線(xiàn)程調(diào)度函數(shù)
    int var = (int)(long)(arg);
    printf("被創(chuàng)建線(xiàn)程id:%lu,傳過(guò)來(lái)的參數(shù):%d\n", pthread_self(), var);
    return NULL;
}

int main(int argc, const char* argv[]) {

    pthread_t tid;
    int ret = -1;

    // 初始化tid。因?yàn)椴皇撬邢到y(tǒng)中的pthread_t都是unsigned int, 因此最好使用memset初始化。
    memset(&tid, 0, sizeof(tid));

    // 創(chuàng)建線(xiàn)程
    ret = pthread_create(&tid, NULL, threadFunc, (void*)0x3);
    if (0 != ret) {
        printf("線(xiàn)程創(chuàng)建失??!\n");
        return 1;
    }
    printf("按下任意鍵繼續(xù)...\n");
    getchar();
    printf("主線(xiàn)程id:%lu\n", pthread_self());

    return 0;
}

運(yùn)行結(jié)果:

3. 線(xiàn)程屬性

typedef struct {
    int etachstate;   // 線(xiàn)程的分離狀態(tài)
    int schedpolicy;  // 線(xiàn)程的調(diào)度策略
    struct sched_param schedparam; // 線(xiàn)程的調(diào)度參數(shù)
    int inheritsched;  // 線(xiàn)程的繼承性
    int scope;         // 線(xiàn)程的作用域
    size_t guardsize;  // 線(xiàn)程棧末尾的警戒緩沖區(qū)大小
    int stackaddr_set; // 線(xiàn)程棧的設(shè)置
    void* stackaddr;   // 線(xiàn)程棧的位置
    size_t stacksize;  // 線(xiàn)程棧的大小
} pthread_attr_t;
/*
功能:
    線(xiàn)程屬性結(jié)構(gòu)體;
主要成員:
    etachstate:線(xiàn)程的分離狀態(tài)
    guardsize:線(xiàn)程棧末尾的警戒緩沖區(qū)大小
    stackaddr:線(xiàn)程棧的位置
    stacksize:線(xiàn)程棧的大小

注意:
    線(xiàn)程屬性值不能直接設(shè)置,需使用相關(guān)函數(shù)進(jìn)行操作。
    如pthread_create之前用pthread_attr_init初始化,
    之后用pthread_attr_destory釋放資源。
*/

(1)線(xiàn)程屬性的初始化和銷(xiāo)毀

#include<pthread.h>

int pthread_attr_init(pthread_attr_t* attr);
/*
功能:
    初始化線(xiàn)程屬性attr。
參數(shù):
    attr:待初始化的線(xiàn)程屬性結(jié)構(gòu)體。
返回值:
    成功:0
    失?。哄e(cuò)誤碼
*/

int pthread_attr_destory(pthread_attr_t* attr);/*
功能:
    銷(xiāo)毀線(xiàn)程屬性attr。
參數(shù):
    attr:線(xiàn)程屬性結(jié)構(gòu)體。
返回值:
    成功:0
    失?。悍?錯(cuò)誤碼
*/

(2)線(xiàn)程分離狀態(tài)屬性設(shè)置

  • 線(xiàn)程分離狀態(tài):無(wú)需其他線(xiàn)程阻塞等待線(xiàn)程結(jié)束以回收已結(jié)束線(xiàn)程的資源,而是讓內(nèi)核回收已結(jié)束線(xiàn)程的資源。
  • 線(xiàn)程非分離狀態(tài):某個(gè)線(xiàn)程(如主線(xiàn)程)阻塞等待子線(xiàn)程結(jié)束以回收其資源。
#include<pthread.h>

int pthread_attr_setdetachstate(pthread_attr_t* attr, int detachstate);
/*
功能:
    設(shè)置線(xiàn)程屬性為分離。
參數(shù):
    attr:已初始化的線(xiàn)程屬性結(jié)構(gòu)體;
    detachstate:是否分離:
        PTHREAD_CREATE_DETACHED:分離
        PTHREAD_CREATE_JOINABLE:非分離
返回值:
    成功:0
    失?。悍?
*/

int pthread_attr_getdetachstate(const pthread_attr_t* attr, int* detachstate);
/*
功能:
    獲取線(xiàn)程是否分離狀態(tài)
參數(shù):
    attr:線(xiàn)程屬性結(jié)構(gòu)體。
        detachstate:是否分離:
        PTHREAD_CREATE_DETACHED:分離
        PTHREAD_CREATE_JOINABLE:非分離
返回值:
    成功:0
    失?。悍?錯(cuò)誤碼
*/

線(xiàn)程設(shè)置分離屬性示例

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

void* func(void* arg) {
    printf("子線(xiàn)程開(kāi)始...\n");
    sleep(2);
    printf("子線(xiàn)程結(jié)束...\n");
    pthread_exit(NULL);
}

int main(int argc, const char* argv[]) {

    int ret = -1;
    pthread_t tid = -1;
    pthread_attr_t attr;

    // 初始化線(xiàn)程屬性
    ret = pthread_attr_init(&attr);
    if (0 != ret) {
        printf("線(xiàn)程屬性初始化失敗。\n");
        return 1;
    }

    // 設(shè)置線(xiàn)程屬性為分離狀態(tài)
    ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    if (0 != ret) {
        printf("線(xiàn)程分離屬性設(shè)置失敗。\n");
        return 1;
    }

    // 創(chuàng)建線(xiàn)程
    ret = pthread_create(&tid, &attr, func, NULL);
    if (0 != ret) {
        printf("線(xiàn)程創(chuàng)建失敗.\n");
        return 1;
    }

    sleep(3);

    // join看看是否為分離狀態(tài)
    ret = pthread_join(tid, NULL);
    if (0 != ret) {
        printf("線(xiàn)程為分離狀態(tài),無(wú)需join.\n");
    } else {
        printf("線(xiàn)程為非分離狀態(tài),已被join.\n");
    }

    // 銷(xiāo)毀線(xiàn)程屬性
    ret = pthread_attr_destroy(&attr);
    if (0 != ret) {
        printf("線(xiàn)程屬性銷(xiāo)毀失敗。\n");
        return 1;
    }

    return 0;
}

運(yùn)行結(jié)果:

(3)線(xiàn)程棧大小獲取和設(shè)置

#include<pthread.h>

int pthread_attr_setstacksize(pthread_attr_t* attr, size_t stacksize);
/*
功能:
    設(shè)置線(xiàn)程棧大小。
參數(shù):
    attr:線(xiàn)程屬性結(jié)構(gòu)體;
    stacksize:線(xiàn)程棧大?。?
返回值:
    成功:0;
    失敗:錯(cuò)誤碼
*/

int pthread_attr_getstacksize(const pthread_attr_t* attr, size_t* stacksize);
/*
功能:
    獲取線(xiàn)程棧大小。
參數(shù):
    attr:線(xiàn)程屬性結(jié)構(gòu)體指針;
    stacksize:返回的線(xiàn)程棧大??;
返回值:
    成功:0;
    失?。悍?錯(cuò)誤碼
*/

4. 線(xiàn)程的回收

(1)pthread_join函數(shù)

主線(xiàn)程回收線(xiàn)程資源,會(huì)阻塞。

#include<pthread.h>

int pthread_join(pthread_t thread, void** retval);
/*
功能:
    類(lèi)似于wait()函數(shù)。等待線(xiàn)程thread結(jié)束,回收線(xiàn)程資源;若線(xiàn)程已結(jié)束,則會(huì)立即返回。
參數(shù):
    thread:等待回收的線(xiàn)程號(hào);
    retval:存儲(chǔ)進(jìn)程退出狀態(tài)的指針的地址;
返回值:
    成功:0
    失敗:非0錯(cuò)誤碼
*/

pthread_join示例:

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

void* func() {
    printf("子線(xiàn)程開(kāi)始執(zhí)行...\n");
    sleep(3);
    printf("子線(xiàn)程結(jié)束執(zhí)行...\n");
    return (void*)0x3;
}

int main(int argc, const char* argv[]) {

    pthread_t tid;
    int ret = -1;
    void* retp = NULL;

    memset(&tid, 0, sizeof(tid));

    // 創(chuàng)建線(xiàn)程
    ret = pthread_create(&tid, NULL, func, NULL);
    if (0 != ret) {
        printf("線(xiàn)程創(chuàng)建失敗.\n");
        return 1;
    }

    printf("主線(xiàn)程執(zhí)行...\n");

    // 等待線(xiàn)程結(jié)束 pthread_join會(huì)阻塞
    ret = pthread_join(tid, &retp);
    if (0 != ret) {
        printf("線(xiàn)程join失敗.\n");
        return 1;
    }

    printf("retp: %p\n", retp);
    printf("主線(xiàn)程退出...\n");

    return 0;
}

運(yùn)行結(jié)果:

(2)pthread_detach函數(shù)

內(nèi)核回收線(xiàn)程資源,不會(huì)阻塞。

#include<pthread.h>

int pthread_detach(pthread_t thread);
/*
功能:
    使線(xiàn)程thread與當(dāng)前進(jìn)程分離,之后線(xiàn)程結(jié)束后的資源回收由內(nèi)核完成,因此不會(huì)阻塞。
參數(shù):
    thread:線(xiàn)程號(hào);
返回值:
    成功:0
    失?。悍?
*/

 pthread_detach示例:

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

void* func(void* arg) {
    printf("子線(xiàn)程開(kāi)始...\n");
    for (int i = 0; i < 3;++i) {
        sleep(1);
        printf("子線(xiàn)程工作%ds\n", i);
    }
    printf("子線(xiàn)程結(jié)束...\n");
    return NULL;
}

int main(int argc, const char* argv[]) {

    int ret = -1;
    pthread_t tid = -1;

    // 創(chuàng)建線(xiàn)程
    ret = pthread_create(&tid, NULL, func, NULL);
    if (0 != ret) {
        printf("線(xiàn)程創(chuàng)建失敗.\n");
        return 1;
    }

    // 設(shè)置線(xiàn)程分離
    ret = pthread_detach(tid);
    if (0 != ret) {
        printf("線(xiàn)程分離失敗.\n");
        return 1;
    }

    printf("主線(xiàn)程:按回車(chē)鍵退出..\n");
    getchar();

    return 0;
}

運(yùn)行結(jié)果:

線(xiàn)程設(shè)置為detach狀態(tài),主線(xiàn)程不必阻塞等待回收子線(xiàn)程資源,而是由內(nèi)核完成。

5. 線(xiàn)程的退出

若在線(xiàn)程中用exit函數(shù)退出,則導(dǎo)致整個(gè)進(jìn)程退出,而非退出這一個(gè)線(xiàn)程。

如下三者可在不結(jié)束整個(gè)進(jìn)程的情況下結(jié)束線(xiàn)程:

a)線(xiàn)程從執(zhí)行函數(shù)中返回;

b)線(xiàn)程調(diào)用pthread_exit退出線(xiàn)程;

c)線(xiàn)程被同一進(jìn)程中的其它線(xiàn)程取消。

pthread_exit函數(shù)

#include<pthread.h>

void pthread_exit(void* retval);
/*
功能:
    退出調(diào)用線(xiàn)程。
參數(shù):
    retval:存儲(chǔ)線(xiàn)程退出狀態(tài)的指針。
*/

6. 線(xiàn)程的取消

pthread_cancel函數(shù)

#include<pthread.h>

int pthread_cancel(pthread_t thread);
/*
功能:
    殺死線(xiàn)程thread;
參數(shù):
    thread:目標(biāo)線(xiàn)程ID;
返回值:
    成功:0
    失?。悍?錯(cuò)誤碼。
*/

pthread_cancel示例:

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

void* func(void* arg) {
    printf("子線(xiàn)程開(kāi)始...\n");
    for (int i = 0; i < 5;++i) {
        sleep(1);
        printf("子線(xiàn)程工作%ds\n", i);
    }
    printf("子線(xiàn)程結(jié)束...\n");
    pthread_exit(NULL);
}

int main(int argc, const char* argv[]) {

    int ret = -1;
    pthread_t tid = -1;

    // 創(chuàng)建線(xiàn)程
    ret = pthread_create(&tid, NULL, func, NULL);
    if (0 != ret) {
        printf("線(xiàn)程創(chuàng)建失敗.\n");
        return 1;
    }

    // 設(shè)置線(xiàn)程分離
    ret = pthread_detach(tid);
    if (0 != ret) {
        printf("線(xiàn)程分離失敗.\n");
        return 1;
    }

    sleep(3);
    pthread_cancel(tid);  // 殺死線(xiàn)程

    printf("主線(xiàn)程:按回車(chē)鍵退出..\n");
    getchar();

    return 0;
}

運(yùn)行結(jié)果:

7. 線(xiàn)程使用注意事項(xiàng)

(1)主線(xiàn)程退出,而其余線(xiàn)程不退出,主線(xiàn)程應(yīng)調(diào)用pthread_exit;

(2)避免僵尸線(xiàn)程方式:

  • a)pthread_join;
  • b)pthread_detach;
  • c)pthread_create前設(shè)置線(xiàn)程分離屬性;

(3)malloc和mmap申請(qǐng)的內(nèi)存可被其他線(xiàn)程釋放;

(4)避免在多線(xiàn)程中fork,除非馬上使用exec;

(5)避免多線(xiàn)程中使用信號(hào)機(jī)制。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • linux下如何搭建文件共享服務(wù)器

    linux下如何搭建文件共享服務(wù)器

    這篇文章主要介紹了linux下如何搭建文件共享服務(wù)器問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-09-09
  • CentOS下使用Squid架設(shè)CDN服務(wù)器的方法

    CentOS下使用Squid架設(shè)CDN服務(wù)器的方法

    這篇文章主要介紹了CentOS下使用Squid架設(shè)CDN服務(wù)器的方法,需要的朋友可以參考下
    2014-07-07
  • 在Linux中配置和使用CAN通信的詳細(xì)指南

    在Linux中配置和使用CAN通信的詳細(xì)指南

    CAN是一種廣泛用于嵌入式系統(tǒng)、汽車(chē)和工業(yè)控制中的通信協(xié)議,Linux 支持 CAN 協(xié)議棧,并通過(guò) SocketCAN 實(shí)現(xiàn)對(duì) CAN 總線(xiàn)的訪(fǎng)問(wèn),在這篇博客中,我們將深入講解如何在 Linux 系統(tǒng)中配置和使用 CAN 通信,需要的朋友可以參考下
    2025-08-08
  • linux禁止ping的實(shí)現(xiàn)實(shí)例

    linux禁止ping的實(shí)現(xiàn)實(shí)例

    這篇文章主要介紹了linux禁止ping的實(shí)現(xiàn)實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 一條命令讓你明白shell中read命令的常用參數(shù)

    一條命令讓你明白shell中read命令的常用參數(shù)

    今天小編就為大家分享一篇關(guān)于一條命令讓你明白shell中read命令的常用參數(shù),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • linux允許端口遠(yuǎn)程訪(fǎng)問(wèn)開(kāi)放端口的方法

    linux允許端口遠(yuǎn)程訪(fǎng)問(wèn)開(kāi)放端口的方法

    今天小編就為大家分享一篇linux允許端口遠(yuǎn)程訪(fǎng)問(wèn)開(kāi)放端口的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • linux服務(wù)監(jiān)控及運(yùn)維

    linux服務(wù)監(jiān)控及運(yùn)維

    本文通過(guò)詳細(xì)介紹安裝psutil包到查找操作系統(tǒng)所有服務(wù)進(jìn)行ID,提取監(jiān)控等內(nèi)容,接下來(lái)我們大家一起來(lái)學(xué)習(xí)吧
    2021-08-08
  • CentOS 7如何快速開(kāi)放端口

    CentOS 7如何快速開(kāi)放端口

    這篇文章主要為大家詳細(xì)介紹了CentOS 7如何快速開(kāi)放端口,如何使用firewalld開(kāi)放Linux端口,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • 詳解如何在Linux中重置MySQL或者M(jìn)ariaDB的root密碼

    詳解如何在Linux中重置MySQL或者M(jìn)ariaDB的root密碼

    本篇文章主要介紹了如何在 Linux 中重置 MySQL 或者 MariaDB 的 root 密碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • Ubuntu系統(tǒng)端口查詢(xún)與管理的詳細(xì)分析

    Ubuntu系統(tǒng)端口查詢(xún)與管理的詳細(xì)分析

    事情起因是寶塔的CPU負(fù)載過(guò)大,重啟服務(wù)進(jìn)程之后還是爆,后續(xù)發(fā)現(xiàn)是端口被占用,導(dǎo)致服務(wù)重啟不起來(lái),所以本文給大家介紹了Ubuntu系統(tǒng)端口查詢(xún)與管理的詳細(xì)分析,需要的朋友可以參考下
    2024-11-11

最新評(píng)論

仁寿县| 漳州市| 项城市| 大同市| 博野县| 大港区| 故城县| 太保市| 葵青区| 武胜县| 瑞金市| 武穴市| 屏山县| 铜山县| 唐海县| 子长县| 上蔡县| 武安市| 姚安县| 扶绥县| 江华| 皮山县| 前郭尔| 武胜县| 大同县| 浏阳市| 临朐县| 永寿县| 凉城县| 鲁山县| 贡嘎县| 萝北县| 永兴县| 石渠县| 鄂州市| 普陀区| 厦门市| 西宁市| 宿松县| 开封县| 洪江市|