Linux 线程概念

Linux中的线程被视为进程内的执行单元,进程作为线程的容器,共享同一资源。内核级线程由内核管理,用户级线程在用户空间实现。线程优点包括低成本创建、资源占用少,能提高并发效率。但过多线程可能导致调度开销,且多线程编程易引发数据一致性问题。当一个线程异常时,可能导致整个进程崩溃。
摘要由CSDN通过智能技术生成

Linux 线程概念

在 Linux 系统中,没有独立的、与线程完全分离的进程实体。实际上,进程可以被视为线程的容器,线程是进程的执行单元。

在传统的操作系统中,进程被认为是独立的实体,具有独立的地址空间、文件描述符、资源等。而在 Linux 中,进程与线程之间没有明显的差异,线程之间共享同一进程的资源,包括内存空间、文件描述符、信号处理等。每个进程至少有一个线程,即主线程,其他线程都是主线程的衍生。

Linux 采用了 轻量级进程(LWP,Lightweight Process)模型,将线程作为进程的基本执行单元 。通过在进程内创建和管理线程,实现并发执行和资源共享。

因此,在 Linux 中,进程只是线程的一个容器,用于提供资源隔离和管理的框架 。每个进程都有一个唯一的进程标识符(PID),用于标识该进程及其线程组。线程之间的切换和调度是通过操作系统内核来完成的 ,进程和线程之间没有明确的边界。

内核级线程与用户级线程

内核级线程:内核级线程是由操作系统内核直接支持和管理的线程。在这种模型中,线程的创建、调度和管理都由操作系统内核 完成。每个内核级线程都有独立的内核栈和内核上下文,由内核进行调度和切换。在内核级线程模型中,多个线程可以并发执行在多个处理器核心上,充分利用多核资源。

用户级线程:用户级线程是在用户空间实现的线程。用户级线程的 创建、调度和管理由用户态的线程库或运行时库完成,而操作系统对这些线程是无感知的 。在 单个内核级线程 上运行的若干个用户级线程,由用户态的调度算法决定线程的切换和执行,不需要操作系统内核的介入,所以线程的切换开销较小。

在这里插入图片描述

在这里插入图片描述

接下来的内容讲的都是内核级线程

线程的优点

  • 线程的创建和销毁成本较低
  • 线程的切换成本低
  • 线程占用的资源少
  • 对于 计算密集型 的程序而言,使用线程可以将计算部分分配到多个线程执行,提高效率
  • 对于 IO 密集型 的程序而言,使用线程可以将 IO 操作重叠,等待多种 IO 操作

线程的缺点

  • 潜在的性能损失:如果开辟的线程数量大于了计算机可用的处理器数量,那么会产生额外的同步和调度开销
  • 健壮性降低:编写多线程程序时,往往会因为数据的不恰当访问而导致数据不一致问题,线程之间是缺乏保护的
  • 缺少访问控制:进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响
  • 编写难度高:调试一个多线程程序往往比单线程程序困难

线程异常

对于一个多线程程序,如果某一个线程出现异常,崩溃,那么对应的进程也会崩溃,其它线程也会跟着退出

例如:

void *thread0(void *arg)
{
    int loops = 3;
    while (loops--)
    {
        printf("Thread0 is running...\n");
        sleep(1);
    }
    raise(SIGABRT); // 线程 1 抛出 SIGABRT
    return NULL;
}

void *thread1(void *arg)
{
    while (1) // 死循环
    {
        printf("Thread1 is running...\n");
        sleep(1);
    }
}

int main(void)
{
    pthread_t tid0, tid1;

    pthread_create(&tid1, NULL, thread1, NULL); // 创建线程 1
    pthread_create(&tid0, NULL, thread0, NULL); // 创建线程 0

    sleep(10); // 等待 thread 0 抛出 SIGABRT
    printf("Main thread is quitting...\n");
    return 0;
}

输出:

在这里插入图片描述

可以看到,当 thread0 抛出异常后,thread1 和 主线程 都退出了

线程与进程

在一开始介绍线程概念的时候,已经讲到了线程与进程的关系,这里再总结一下:

  • 进程是资源分配的基本单位,线程是调度的基本单位

  • 线程共享进程的资源,包括内存空间、文件描述符、每种 信号处理的方式

  • 线程也有自己独享的资源:

    • 线程 ID
    • 一组寄存器(用于保存上下文数据和调度)
    • 栈区(线程的临时数据)
    • errno
    • 屏蔽信号集
    • 调度优先级

根据「进程是线程的容器」这句话理解二者的关系可能更加容易

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值