Linux | 线程概念以及创建与等待

本文介绍Linux环境下线程的概念及其实现原理,详细讲解了如何使用pthread库创建和管理线程,包括线程创建、线程等待及线程退出等关键操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程概念

Linux操作系统并不是真线程操作系统,意味着没有专门描述组织线程的内核数据结构,所有线程都是通过进程PCB模拟的.

什么是进程,进程如何模拟线程?

进程概念:

进程是系统分配程序资源的基本单位,如虚拟内存,页表,文件描述符表,信号集...这些资源都是按照进程为单位来分配的!

cpu拿到进程PCB就可以通过它指向的进程资源(虚拟内存,页表等),找到程序的代码和数据.所以PCB就称作一个执行流.

那一个进程可不可有多个PCB指向相同的系统资源呢?

当然可以,而这样的做,就是线程的基本原理!

线程概念:

线程是cpu调度的基本单位,而一个进程下可以有多个线程,他们共用同一套进程资源!

 结合这张图和上述概念,一些书上的概念就很容易理解了,什么是线程:

1.在进程内部运行的执行流

2.线程比进程的粒度更细,调度成本更低(线程不需要像切换进程那样切换进程资源)

3.线程是CPU调度的基本单元

创建和等待线程

pthread库

由于系统提供的接口过于复杂,所以除去部分语言自带的线程库之外,普遍使用pthread库来做线程相关的操作.

pthread虽然是第三方库,但却是系统自带的,不需要手动下载安装,使用时只需要包含头文件pthread.h 编译时添加选项 -lpthread 即可.

本文用最简单c语言,使用pthread库完成线程的相关操作

创建线程

参数1:pthread_t 是库中提供的线程id类型,此处为输出型参数,需传入一个pthread_t的地址来接收新建线程的id.
参数2: 用来设置特殊属性,一般情况设置为nullptr.

参数3:传入要线程执行的函数,(可以理解为线程的主函数)注意返回值和参数都是void*类型

参数4:参数3函数的参数,void*类型,传参很灵活.

返回值:创建成功返回0,否则返回的错误码.

创建成功后,main函数对应的执行流就是主线程,其他的就称为子线程. 主线程return 代表进程退出,所有的线程都会被退出,进程的资源会被回收.

代码案例:

//头文件 pthread.h
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *thread_routine(void *argc)
{
    printf("%s : start running\n",(char*)argc);
    //other work
    sleep(1);
    //exit
    printf("exit\n");
    return NULL;
}
int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,thread_routine,(void*)"thread_1");
    sleep(5);
    return 0;
}

线程退出有2种方式,

1.return 返回值 

2.pthread_exit(返回值) 

void *thread_routine(void *argc)
{
    printf("%s : start running\n",(char*)argc);
    //other work
    sleep(1);
    //exit
    printf("exit\n");
    //退出方式1
    //return NULL;
    //退出方式2
    //pthread_exit(NULL);
}

只有通过线程等待,才能获取线程的返回值!

线程等待

参数1:要等待的线程id.

参数2:输出型参数,用来接收线程的返回值. 不需要获取可以传nullptr

调用这个函数,会阻塞等待线程退出,获取线程返回值 ,并回收线程资源!

所以上面的代码案例是有问题的,会导致线程资源没有被主线程回收,造成内核资源泄漏.

改进后:

//头文件 pthread.h
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *thread_routine(void *argc)
{
    printf("%s : start running\n", (char *)argc);
    // other work
    sleep(1);
    // exit
    printf("exit\n");
    //退出方式1
    // return NULL;
    //退出方式2
    pthread_exit(NULL);
}
int main()
{
    pthread_t tid_1, tid_2, tid_3;
    pthread_create(&tid_1, NULL, thread_routine, (void *)"thread_1");
    pthread_create(&tid_2, NULL, thread_routine, (void *)"thread_2");
    pthread_create(&tid_3, NULL, thread_routine, (void *)"thread_3");
    void *thread_ret;                 //输出型参数
    pthread_join(tid_1, &thread_ret); //阻塞等待
    printf("join succeed return value:%d\n", (long int)thread_ret);
    pthread_join(tid_2, &thread_ret); //阻塞等待
    printf("join succeed return value:%d\n", (long int)thread_ret);
    pthread_join(tid_3, &thread_ret); //阻塞等待
    printf("join succeed return value:%d\n", (long int)thread_ret);
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值