Linux - 信号和线程

信号:signal

  1. 在Linux中,信号是一种用于通知进程发生了某种事件的机制,可以理解为信号是软件中断

  2. 信号可以由内核、其他进程或者通过命令行工具发送给目标进程

  3. Linux系统中有多种信号,每种信号都用一个唯一的整数值来表示

  4. 常见的信号:

    信号1

  5. 常见的信号函数:

    • kill() 给指定进程(PID)发送信号(signal 编号)
    • alarm() 在 seconds(参数) 秒后,向调用进程发送一个 SIGALRM 信号, SIGALRM 信号的默认动作是终止调用 alarm 函数的进程
    • raise() 给调用进程本身送一个信号
    • abort() 向当前进程发送一个 SIGABRT 信号,默认情况下进程会退出
    • pause() 将调用进程挂起直至捕捉到信号为止。这个函数通常用于判断信号是否已到
  6. 信号处理函数:signal()

    1
    2
    3
    #include <signal.h>
    typedef void (*sighandler_t)(int);
    sighandler_t signal(int signum, sighandler_t handler);
    • 函数功能:

      • 注册信号处理函数(不可用于 SIGKILL(9) 、 SIGSTOP(19) 信号)即确定收到信号后处理函数的入口地址
      • 收到某个信号之后,不再使用默认的系统处理方式,而是我们指定的处理方式
    • 函数参数:

      • signum 信号编号

      • handler 信号处理函数

        信号2

    • 返回值:

      • 成功:返回函数地址,该地址为此信号上一次注册的信号处理函数的地址
      • 失败:返回 SIG_ERR
  7. 信号集:用来表示多个信号的数据类型

线程:thread

  1. 线程:是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位,一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务

  2. 一个进程可以有很多线程,每条线程并行执行不同的任务

  3. 同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等,但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)

  4. 并发:Concurrency

    1. 定义:指多个任务在同一时间段内交替执行,但同一时刻只有一个任务在运行
    2. 通过时间片(时间轮询) 或事件驱动的方式交替处理,宏观上看起来像是同时进行
    3. 本质是逻辑上的同时性,而非物理上的并行执行
    4. 可在单处理器或多处理器系统中实现
  5. 并行:Parallelism

    1. 定义:指多个任务在同一时刻同时执行,每个任务由独立的处理器或核心处理
    2. 真正实现物理上的多个任务同时执行,依赖硬件资源,需要多核/多处理器硬件支持
    3. 本质是物理上的同时性,需要硬件支持
    4. 仅在多处理器或分布式系统中实现
  6. 进程与线程的关系:

    • 进程(Process)是正在执行的程序的实例,每个进程都有自己的地址空间、代码段、数据段和打开的文件描述符等资源。线程(Thread)是进程内的一个执行单元,它共享相同的地址空间和其他资源,包括文件描述符、信号处理等,但每个线程都有自己的栈空间
    • 由于共享地址空间和数据段,同一进程的多线程之间进行数据交换比进程间通信方便很多,但也由此带来线程同步问题
    • 同一进程的多个线程共享大部分的资源,除了每个线程独立的栈空间,这代表线程的创建、销毁、切换要比进程的创建、销毁、切换的资源消耗小很多,所以多线程比多进程更适合高并发
  7. 图解:

    线程1

    线程2

参考链接: