博客
关于我
初夏小谈:全面剖析多线程(一)
阅读量:836 次
发布时间:2019-03-25

本文共 1582 字,大约阅读时间需要 5 分钟。

多线程及其控制

在编程中,多线程能够同时进行多个任务,这极大地提高了程序的效率。然而,在深入理解多线程之前,我们需要先了解其基础——进程和线程的关系。


1. 进程与线程的关系

进程是运行中的程序,是操作系统分配资源的基本单位。每启动一个程序,操作系统会为它创建一个进程控制块(PCB),这是进程的唯一标识。例如,在Linux下,进程可以视为task_struct结构体。

在Linux系统中,线程是通过模拟轻量级进程来实现的,即线程在内核层被看作轻量级进程。这样设计使得线程比传统的进程更加高效,但同样需要有进程来管理资源分配和调度。每个进程至少包含一个线程(线程组),而进程内部可以包含多个线程。线程和进程的关系可以理解为:线程是资源(如CPU调度)的基本单位,而进程则是资源分配的基本单位。


2. 多线程的数据共享与独有部分

多线程应用程序中,线程之间共享一些资源,但也有一些独有的资源。

  • 共享数据

    • 文件描述符
    • 信号处理方式(如SIG_IGNSIG_DFL或自定义信号处理函数)
    • 当前工作目录
    • 用户ID和组ID
  • 独有数据

    • 栈和寄存器
    • 信号屏蔽字
    • 错误信息(如_errno
    • 线程标识符

由于每个线程都有自己的PCB,多线程程序能够在不同的时间点为每个线程分配CPU资源,从而避免了栈深度过大的问题。


3. 多线程的优缺点

多线程的使用在CPU密集型或IO密集型应用中都有其优势。以下是多线程的主要优缺点:

优点:
  • 线程间通信简单:共享虚拟地址空间,减少了对共享内存的复杂操作。
  • 创建/销毁成本低:线程的生命周期管理比进程更高效。
  • 调度成本低:由于线程的调度直接由内核完成,效率较高。
  • 执行粒度细:可以将任务划分为更小的线程,提升性能。
  • 缺点:
  • 缺乏访问控制:一个线程的错误可能导致整个进程的失败。
  • 健壮性较低:线程的某些问题可能导致整个应用崩溃。

  • 4. 多线程控制

    在Linux系统中,由于没有真正的线程模型,实现多线程控制需要依赖线程库(例如pthread)。这些库提供了一套接口,用于线程的创建、终止、等待和分离等操作。

    1. 线程创建

    使用pthread_create函数创建线程。该函数的参数包括:

    • thread:存储线程ID的整数
    • attr:线程属性结构体,通常置NULL
    • start_routine:线程入口函数
    • arg:传递给线程的参数
    2. 线程终止

    线程可以在其入口函数返回时退出,或者在主线程调用pthread_exit终止。可以使用pthread_cancel取消指定线程,但应谨慎操作,因为这可能产生僵尸线程。

    3. 线程等待

    使用pthread_join函数等待线程退出。此时,如果线程的joinable属性被保留,资源将被合理释放,避免僵尸线程的出现。

    4. 线程分离

    通过pthread_detach函数将线程的joinable属性修改为SINGLE threaded Detach,使其退出后自动释放资源。分离线程后,使用pthread_join将无法获取线程的返回值。

    5. 线程安全

    多线程程序需要确保多个线程访问共享资源时的正确性,这可以通过同步机制实现。常用的方法包括互斥锁和条件变量。


    相关技术

    为了实现线程安全,常用以下技术:

    互斥锁

    互斥锁确保在同一时间内只有一个线程可以访问共享资源。常用的实现方式包括:

    • POSIX互斥锁(pthread_mutex
    • Windows互斥锁(CRITICAL_SECTION

    条件变量

    条件变量用于线程间的同步和唤醒。常见实现方式如下:

    • 传统条件变量(pthread_cond
    • Windows条件事件

    这些机制结合使用,可以实现线程安全,确保多线程程序的正确性。


    通过上述知识,我们可以清晰地理解多线程的概念及其控制方式。这对于开发高效且健壮的多线程应用程序至关重要。

    转载地址:http://aicuk.baihongyu.com/

    你可能感兴趣的文章
    mysql 删除日志文件详解
    查看>>
    mysql 判断表字段是否存在,然后修改
    查看>>
    MySQL 到底能不能放到 Docker 里跑?
    查看>>
    mysql 前缀索引 命令_11 | Mysql怎么给字符串字段加索引?
    查看>>
    MySQL 加锁处理分析
    查看>>
    mysql 协议的退出命令包及解析
    查看>>
    mysql 参数 innodb_flush_log_at_trx_commit
    查看>>
    mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
    查看>>
    MySQL 命令和内置函数
    查看>>
    mysql 四种存储引擎
    查看>>
    MySQL 在并发场景下的问题及解决思路
    查看>>
    MySQL 基础架构
    查看>>
    MySQL 基础模块的面试题总结
    查看>>
    MySQL 备份 Xtrabackup
    查看>>
    mYSQL 外键约束
    查看>>
    mysql 多个表关联查询查询时间长的问题
    查看>>
    mySQL 多个表求多个count
    查看>>
    mysql 多字段删除重复数据,保留最小id数据
    查看>>
    MySQL 多表联合查询:UNION 和 JOIN 分析
    查看>>
    MySQL 大数据量快速插入方法和语句优化
    查看>>