线程相关概念

112 阅读4分钟

4月「掘金·日新计划」第8天

一、概念

总的来说,线程的优点缺点,都是来自内存地址共享 健壮性,切换效率,节俭,通信

1.1、线程是什么

  1. 一个进程最少有一个线程
  2. 同一时刻做多件事情
  3. 同一进程的多个线程共享进程地址空间

1.2、进程线程区别

  1. 健壮性(进程更健壮)

    1. 进程:有独立地址空间,崩溃不会影响其他
    2. 线程:没有单独地址空间,崩溃等于进程崩溃
  2. 效率(线程高)

    1. 进程切换资源消耗大,效率差
    2. 对要求同时并共享变量,并发操作,只能线程

1.3、使用线程的理由优点

  1. 节俭的多任务操作方式

    1. 共享进程地址空间,进程是独立地址空间(耗内存
    2. 切换效率时间:线程>进程,开销进程远远大于线程(大约30倍)
  2. 通信机制方便

    1. 因为内存共享

1.4、选择多进程还是多线程

内存,数据通信,线程安全(竞争死锁问题)

1.5、多线程开发api

  1. 包含3点:线程,互斥锁,条件

  2. 线程

    1. 创建,退出,等待

    2. 可以传递参数进入线程(也可以全局变量不需要传递,直接使用)

      传结构体指针数组,要强转为二级指针承接,然后p[0]使用

    3. 线程退出也可以传递数据回来,需要加static,不然会被释放

    4. 等待,会阻塞等待线程退出

  3. 互斥量(mutex)

    1. 创建,销毁,加锁,解锁

    2. 拿到锁的线程加锁,剩下线程拿不到锁阻塞等待锁释放

    3. 保证临界资源不在同一时间被修改访问

    4. 应该注意:

      1. 尽量保证锁的粒度, 越小越好。(访问共享数据前,加锁。访问结束立即解锁。)
    5. 线程同步的四种方式:互斥锁,条件变量,读写锁,信号量

    6. 信号量:允许多个线程进入临界区,信号量允许被调度和睡眠,锁的竞争者会转入睡眠(信号量不能用于中断上下文,只能进程上下文。自旋锁可以中断上下文)

    7. 自旋锁:持有者临界区不允许被抢占,不允许调度和睡眠

    8. 读写自旋锁:允许多个读获得读锁,1个写获得写锁,读是共享锁,写是互斥锁

    9. 顺序锁:读写锁会导致写锁等待,顺序锁赋予写锁高优先权(写持有锁,读者就要多次执行临界区代码)

    10. 读写锁:与互斥量类似,但读写锁允许更高的并行性。其特性为:写独占,读共享。读锁、写锁并行阻塞,写锁优先级高

  4. 条件

    1. 创建,销毁,触发,广播,等待

    2. 触发:向一个线程发消息。广播:向多个发消息

    3. 宏初始化(静态初始化),函数是动态初始化

    4. 同步,就是按照预定的先后顺序运行,一个锁

      按照某种特定的顺序访问临界资源,从而有效避免饥饿问题

1.6、死锁

  1. 有几种原因

    1. 线程试图对同一个互斥量 A 加锁两次
    2. 线程 1 拥有 A 锁,请求获得 B 锁;线程 2 拥有 B 锁,请求获得 A 锁
    3. 加锁之后忘记解锁
  2. 造成2个线程都不能继续运行下去

1.7、生产者消费者

  1. 概念

    1. 一个进程里面有多个线程,分别扮演消费者和生产者两类
    2. 其中生产者为消费者提供任务,消费者去拿到任务并且执行任务
    3. 而他们之间的“交易场所”为内存块,即全局变量
    4. 一个放,一个拿
  2. 生产者消费者模型优点

    1. 解耦

      因为多了一个缓冲区,所以生产者和消费者并不直接相互调用

    2. 支持并发

      生产者和消费者就是两个独立的并发体

    3. 支持忙闲不均

    4. 效率高