当前位置:首页>Linux>重温并发任务:Linux 多线程同步利器屏障

重温并发任务:Linux 多线程同步利器屏障

  • 2026-02-06 10:05:21
重温并发任务:Linux 多线程同步利器屏障

点击↑深色口袋物联,选择关注公众号,获取更多内容,不迷路


在glibc2.35中,pthread线程提供了5种同步机制,分别为条件变量、互斥锁、读写锁、自旋锁和屏障,本篇主要回顾屏障

一、pthread 屏障的核心作用

✅ 核心定义

在glibc2.35中,线程屏障的定义在sysdeps/nptl/bits/pthreadtypes.h中pthread_barrier_t

typedef union
{
  char __size[__SIZEOF_PTHREAD_BARRIER_T];
  long int __align;
} pthread_barrier_t;

屏障的定义采用了和互斥锁、条件变量一样的 “不透明类型” 设计模式。屏障的逻辑非常复杂,它内部需要记录“需要等待的总线程数”、“当前已到达的线程数”、“当前的阶段(第几轮同步)”以及“用于挂起线程的队列”。glibc 开发者不希望用户直接操作这些字段,所以隐藏在 char 数组后面

✅ 核心作用 & 设计初衷

屏障的核心作用:实现多线程的「同步会合」,保证一组线程在某一阶段完成后,再统一进入下一阶段

  • • 线程到达屏障点:调用pthread_barrier_wait(),线程进入阻塞状态;
  • • 等待所有线程:直到到达屏障点的线程数等于屏障初始化时设置的「目标线程数」;
  • • 释放所有线程:所有等待的线程被同时唤醒,继续执行后续逻辑;
  • • 可复用性:默认屏障是「单次触发」,但部分实现支持「循环屏障」(重置后可复用)。

简单说:屏障解决了「多线程阶段式协作」的问题,比如「所有线程完成数据加载后,再统一进行计算」「所有线程完成初始化后,再统一开始任务」,是比条件变量更简洁的「多线程会合」方案。

✅ 屏障解决的核心痛点

在多线程阶段式任务中,传统同步方式(互斥锁 + 条件变量)存在明显缺陷:

  • • 实现复杂:需要手动维护「已到达线程数」计数器,结合互斥锁保护计数、条件变量唤醒线程,代码冗余且易出错;
  • • 效率低:条件变量唤醒时可能出现「惊群效应」,多次唤醒导致性能损耗;
  • • 不可复用:计数器需手动重置,复用成本高;
  • • 屏障的优势:封装了「计数 + 等待 + 唤醒」逻辑,一行代码实现多线程会合,简洁高效且无惊群效应。

✅ 屏障的底层执行逻辑(极简版,易懂)

  1. 1. 屏障初始化:设置需要等待的「目标线程数」count
  2. 2. 线程到达屏障:调用pthread_barrier_wait(),内核原子性将「已到达数」+1;
  3. 3. 等待判断 :
    • • 已到达数 < count → 线程阻塞,加入屏障等待队列;
    • • 已到达数 = count → 唤醒队列中所有线程,重置已到达数(部分实现);
  4. 4. 线程唤醒:所有线程同时继续执行,其中一个线程会返回PTHREAD_BARRIER_SERIAL_THREAD(可作为「主线程」执行汇总逻辑),其余线程返回 0。

二、pthread 屏障 核心使用场景

屏障的核心价值是「多线程会合」,所有场景都围绕「阶段式任务」展开,覆盖 Linux 多线程开发的高频协作场景,在匹配场景下,是代码最简洁、效率最高的同步方案,按使用频率排序如下:

✅ 场景 1:多线程数据加载 / 初始化(最核心场景,占比 60%)

  • • 业务逻辑:程序启动时,多个线程并行加载不同数据源(如配置文件、数据库数据、缓存数据),需所有线程加载完成后,再统一进入业务处理阶段;
  • • 同步需求:保证所有数据加载完成,避免业务逻辑访问未加载的数据;
  • • 典型案例:大数据系统的数据源预加载、游戏服务器的资源初始化、嵌入式设备的多模块初始化。

✅ 场景 2:多线程分块计算(高频优化场景)

  • • 业务逻辑:将一个大任务拆分为多个子任务,分配给多个线程并行计算,需所有线程完成分块计算后,再由一个线程汇总计算结果;
  • • 同步需求:保证所有分块计算完成,汇总结果准确;
  • • 典型案例:矩阵乘法的分块计算、大数据排序的分治归并、图像渲染的分块处理。

✅ 场景 3:多线程性能测试(进阶场景)

  • • 业务逻辑:性能测试时,需要所有测试线程同时开始执行,避免线程启动时间差导致测试结果不准;
  • • 同步需求:所有线程在「起点」处会合,同时开始执行测试用例;
  • • 核心优势:相比sleep同步,屏障能精准控制线程启动时间,测试结果更准确。

✅ 场景 4:多进程 / 多节点协作(生产级场景)

  • • 业务逻辑:多进程(或分布式节点)的线程需要同步执行某一阶段任务,如分布式计算的「数据分片处理→结果汇总」;
  • • 同步需求:跨进程 / 节点的线程会合,保证阶段一致性;
  • • 实现方式:屏障存储在共享内存中,设置PTHREAD_PROCESS_SHARED属性,实现跨进程同步。

✅ 场景 5:多线程阶段式任务调度(进阶优化场景)

  • • 业务逻辑:任务分为多个阶段(如「数据采集→数据清洗→数据分析→结果输出」),每个阶段需所有线程完成后,再进入下一阶段;
  • • 同步需求:保证阶段间的依赖关系,避免跨阶段执行;
  • • 典型案例:流水线式数据处理、自动化测试的多阶段执行。

三、pthread 屏障 核心接口(全量 + 详解,背会即用)

屏障的接口全部在 <pthread.h> 头文件中,编译时必须加 -lpthread 链接线程库,所有接口返回值:成功返回 0,失败返回错误码(非 errno,需手动处理)

✅ 1. 屏障的初始化(唯一方式)

其中参数3, count核心参数,表示需要等待的目标线程数(必须 > 0,否则返回 EINVAL);count一旦设置,默认无法修改(部分系统支持属性修改)。

int pthread_barrier_init(pthread_barrier_t *restrict barrier, 
                         const pthread_barrierattr_t *restrict attr, 
                         unsigned int count);

✅ 2. 屏障的销毁

释放屏障占用的内核资源(等待队列、计数器等);
其中:① 必须与pthread_barrier_init 成对调用; ② 屏障有线程等待时不能销毁(返回 EBUSY 错误);③ 销毁后的屏障若需复用,需重新初始化。

int pthread_barrier_destroy(pthread_barrier_t *barrier);

✅ 3. 等待屏障(核心接口)

调用线程进入屏障等待,直到所有count个线程都调用该函数;所有线程到达后,所有线程同时被唤醒

int pthread_barrier_wait(pthread_barrier_t *barrier);

返回值有3种情况:

  • • 0:普通线程,唤醒后直接继续执行;
  • • PTHREAD_BARRIER_SERIAL_THREAD「串行线程」(仅一个线程返回此值),可用于执行汇总、清理等独有的逻辑
  • • 非0:错误

四、pthread 屏障 核心对比

✅ 对比 1:屏障 vs 条件变量(最核心对比)

二者都是「同步机制」,核心差异在「多线程会合」的实现复杂度:

特性
屏障 (pthread_barrier_t)
条件变量 (pthread_cond_t)
核心规则
等待指定数量线程会合后,同时唤醒
等待条件满足后,唤醒一个 / 所有线程
实现复杂度
低(一行代码实现会合)
高(需手动维护计数器 + 互斥锁)
唤醒方式
所有线程同时唤醒,无惊群效应
广播唤醒有惊群效应,逐个唤醒效率低
复用性
需手动销毁 / 初始化复用
可通过条件重置复用
适用场景
多线程(≥3)阶段式会合
两个线程同步、条件触发
跨进程支持
支持(设置共享属性)
支持(设置共享属性)

✅ 核心结论:多线程会合用屏障,两个线程 / 条件触发用条件变量

✅ 对比 2:屏障 vs 互斥锁(功能边界对比)

二者是「同步 vs 互斥」的本质区别:

特性
屏障
互斥锁 (pthread_mutex_t)
核心职责
多线程同步会合
保护共享资源互斥访问
阻塞逻辑
等待线程数达标后唤醒
锁空闲则持有,否则阻塞
资源保护
有(原子操作保护共享资源)
适用场景
阶段式任务协作
共享资源读写保护
性能
唤醒开销低(无惊群)
加解锁开销低

✅ 核心结论:同步会合用屏障,资源保护用互斥锁

✅ 对比 3:屏障 vs 读写锁(pthread_rwlock_t)

特性
屏障
读写锁
核心规则
多线程会合
多读共享、单写排他
核心价值
阶段式同步
多读并发性能优化
实现复杂度
适用场景
多线程协作
多读少写的资源保护
阻塞逻辑
等待线程数达标
读 / 写互斥等待

✅ 选型原则:阶段式同步用屏障,多读少写用读写锁

✅ 对比 4:单次屏障 vs 循环屏障(功能扩展对比)

特性
单次屏障(POSIX 标准)
循环屏障(部分系统支持)
触发后行为
计数器重置,需重新初始化
自动重置,可直接复用
实现方式
标准接口,兼容性好
扩展属性,兼容性差
适用场景
简单阶段式任务
高频复用的阶段式任务
代码复杂度
高(需手动销毁 / 初始化)
低(自动复用)

✅ 核心结论:优先使用单次屏障(兼容性),高频复用可尝试循环屏障

五、pthread 屏障 3 个可运行实战示例

代码才是硬道理,下面举3个例子

✅ 示例一:多线程初始化会合

实现最经典的「多线程初始化会合」场景:

  1. 1. 5 个线程并行加载不同数据源,模拟初始化操作;
  2. 2. 所有线程加载完成后,在屏障处会合;
  3. 3. 会合后,所有线程统一进入业务处理阶段;
  4. 4. 其中一个串行线程执行初始化汇总逻辑。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>

#define THREAD_NUM 5 // 参与屏障的线程数

// 屏障(全局变量,方便所有线程访问)
pthread_barrier_t barrier;

// 线程函数:模拟数据加载+屏障会合
void* load_data(void* arg)
{
    int tid = *(int*)arg;
    printf("线程%d:开始加载数据源%d...\n", tid, tid);

    // 模拟数据加载耗时(1-3秒随机)
    sleep(1 + rand() % 3);
    printf("线程%d:数据源%d加载完成,到达屏障等待...\n", tid, tid);

    // 等待屏障:所有线程到达后继续
    int ret = pthread_barrier_wait(&barrier);
    if (ret == PTHREAD_BARRIER_SERIAL_THREAD) {
        // 仅一个线程执行汇总逻辑
        printf("=====================================\n");
        printf("串行线程(线程%d):所有数据源加载完成,执行初始化汇总!\n", tid);
        printf("=====================================\n");
    } else if (ret != 0) {
        fprintf(stderr, "线程%d:屏障等待失败,错误码=%d\n", tid, ret);
        pthread_exit(NULL);
    }

    // 所有线程统一进入业务处理阶段
    printf("线程%d:进入业务处理阶段...\n", tid);
    sleep(1); // 模拟业务处理
    printf("线程%d:业务处理完成\n", tid);

    return NULL;
}

int main()
{
    pthread_t tid[THREAD_NUM];
    int tid_arr[THREAD_NUM] = {1,2,3,4,5};

    // 初始化随机数种子
    srand((unsigned int)time(NULL));

    // 初始化屏障:目标线程数=THREAD_NUM
    int ret = pthread_barrier_init(&barrier, NULL, THREAD_NUM);
    if (ret != 0) {
        fprintf(stderr, "屏障初始化失败,错误码=%d\n", ret);
        return -1;
    }

    // 创建5个线程
    for (int i=0; i<THREAD_NUM; i++) {
        ret = pthread_create(&tid[i], NULL, load_data, &tid_arr[i]);
        if (ret != 0) {
            fprintf(stderr, "创建线程%d失败,错误码=%d\n", i+1, ret);
            return -1;
        }
    }

    // 等待所有线程完成
    for (int i=0; i<THREAD_NUM; i++) {
        pthread_join(tid[i], NULL);
    }

    // 销毁屏障(确保所有线程已离开屏障)
    ret = pthread_barrier_destroy(&barrier);
    if (ret != 0) {
        fprintf(stderr, "屏障销毁失败,错误码=%d\n", ret);
        return -1;
    }

    printf("主线程:所有任务完成,程序正常退出\n");
    return 0;
}

运行结果

  • • 所有线程加载完成后才会进入业务处理阶段,体现「阶段式会合」;
  • • 仅一个串行线程执行汇总逻辑,避免重复操作;
  • • 屏障初始化的count严格等于线程数,无永久阻塞风险。
线程1:开始加载数据源1...
线程2:开始加载数据源2...
线程3:开始加载数据源3...
线程4:开始加载数据源4...
线程5:开始加载数据源5...
线程1:数据源1加载完成,到达屏障等待...
线程3:数据源3加载完成,到达屏障等待...
线程2:数据源2加载完成,到达屏障等待...
线程5:数据源5加载完成,到达屏障等待...
线程4:数据源4加载完成,到达屏障等待...
=====================================
串行线程(线程4):所有数据源加载完成,执行初始化汇总!
=====================================
线程4:进入业务处理阶段...
线程1:进入业务处理阶段...
线程3:进入业务处理阶段...
线程2:进入业务处理阶段...
线程5:进入业务处理阶段...
线程4:业务处理完成
线程1:业务处理完成
线程3:业务处理完成
线程2:业务处理完成
线程5:业务处理完成
主线程:所有任务完成,程序正常退出

✅ 示例二: 多阶段屏障复用

实现多阶段任务的屏障复用,覆盖「销毁→重新初始化」的核心规则:

  1. 1. 任务分为 3 个阶段:数据采集→数据清洗→结果输出;
  2. 2. 每个阶段使用独立的屏障(或复用屏障,销毁后重新初始化);
  3. 3. 每个阶段所有线程会合后,再进入下一阶段;
  4. 4. 严格控制屏障的创建和销毁,避免复用异常。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>

#define THREAD_NUM 4 // 线程数
#define PHASE_NUM 3  // 任务阶段数

// 屏障(每个阶段复用)
pthread_barrier_t barrier;
// 阶段名称
const char* phase_names[] = {"数据采集", "数据清洗", "结果输出"};

// 线程函数:多阶段任务+屏障会合
void* process_task(void* arg)
{
    int tid = *(int*)arg;

    for (int phase=0; phase<PHASE_NUM; phase++) {
        // 执行当前阶段任务
        printf("线程%d:开始%s阶段...\n", tid, phase_names[phase]);
        usleep(500000 + rand() % 500000); // 模拟任务耗时(0.5-1秒)
        printf("线程%d:%s阶段完成,到达屏障等待...\n", tid, phase_names[phase]);

        // 等待屏障:所有线程完成当前阶段
        int ret = pthread_barrier_wait(&barrier);
        if (ret == PTHREAD_BARRIER_SERIAL_THREAD) {
            printf("=====================================\n");
            printf("串行线程(线程%d):所有线程完成【%s】阶段!\n", tid, phase_names[phase]);
            printf("=====================================\n");
        } else if (ret != 0) {
            fprintf(stderr, "线程%d:第%d阶段屏障等待失败,错误码=%d\n", tid, phase+1, ret);
            pthread_exit(NULL);
        }

        // 阶段切换:销毁当前屏障,为下一阶段初始化(最后一阶段无需)
        if (phase < PHASE_NUM - 1) {
            pthread_barrier_destroy(&barrier);
            pthread_barrier_init(&barrier, NULL, THREAD_NUM);
        }
    }

    printf("线程%d:所有阶段完成,退出\n", tid);
    return NULL;
}

int main()
{
    pthread_t tid[THREAD_NUM];
    int tid_arr[THREAD_NUM] = {1,2,3,4};

    // 初始化随机数种子
    srand((unsigned int)time(NULL));

    // 初始化第一阶段的屏障
    int ret = pthread_barrier_init(&barrier, NULL, THREAD_NUM);
    if (ret != 0) {
        fprintf(stderr, "屏障初始化失败,错误码=%d\n", ret);
        return -1;
    }

    // 创建线程
    for (int i=0; i<THREAD_NUM; i++) {
        pthread_create(&tid[i], NULL, process_task, &tid_arr[i]);
    }

    // 等待所有线程完成
    for (int i=0; i<THREAD_NUM; i++) {
        pthread_join(tid[i], NULL);
    }

    // 销毁最后一阶段的屏障
    pthread_barrier_destroy(&barrier);

    printf("主线程:所有阶段任务完成,程序正常退出\n");
    return 0;
}

运行结果

  • • 每个阶段完成后销毁并重新初始化屏障,实现复用;
  • • 严格保证每个阶段的线程会合,避免跨阶段执行;
  • • 串行线程在每个阶段执行汇总,确保阶段间的一致性
线程1:开始数据采集阶段...
线程2:开始数据采集阶段...
线程3:开始数据采集阶段...
线程4:开始数据采集阶段...
线程1:数据采集阶段完成,到达屏障等待...
线程2:数据采集阶段完成,到达屏障等待...
线程3:数据采集阶段完成,到达屏障等待...
线程4:数据采集阶段完成,到达屏障等待...
=====================================
串行线程(线程4):所有线程完成【数据采集】阶段!
=====================================
线程1:开始数据清洗阶段...
线程2:开始数据清洗阶段...
线程3:开始数据清洗阶段...
线程4:开始数据清洗阶段...
...(中间阶段略)
=====================================
串行线程(线程2):所有线程完成【结果输出】阶段!
=====================================
线程1:所有阶段完成,退出
线程2:所有阶段完成,退出
线程3:所有阶段完成,退出
线程4:所有阶段完成,退出
主线程:所有阶段任务完成,程序正常退出

✅ 示例三:跨进程屏障同步

实现跨进程的屏障同步,覆盖「共享属性设置」「共享内存」核心知识点:

  1. 1. 父进程创建共享内存,初始化跨进程屏障(设置PTHREAD_PROCESS_SHARED);
  2. 2. 父进程创建子进程,子进程和父进程的线程共享屏障;
  3. 3. 所有进程的线程在屏障处会合,完成跨进程同步;
  4. 4. 严格遵守跨进程屏障的使用规则,无同步异常。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>

#define THREAD_NUM_PER_PROC 2 // 每个进程的线程数
#define PROC_NUM 2            // 进程数
#define TOTAL_THREAD_NUM (THREAD_NUM_PER_PROC * PROC_NUM) // 总线程数

// 共享内存中的数据结构
typedef struct {
    pthread_barrier_t barrier; // 跨进程屏障
    int flag;                  // 同步标志
} SharedData;

// 共享内存指针
SharedData* shared_data;

// 线程函数:跨进程屏障等待
void* thread_func(void* arg)
{
    int tid = *(int*)arg;
    pid_t pid = getpid();

    printf("进程%d线程%d:开始执行任务...\n", pid, tid);
    sleep(1); // 模拟任务耗时
    printf("进程%d线程%d:任务完成,到达跨进程屏障等待...\n", pid, tid);

    // 等待跨进程屏障
    int ret = pthread_barrier_wait(&shared_data->barrier);
    if (ret == PTHREAD_BARRIER_SERIAL_THREAD) {
        printf("=====================================\n");
        printf("进程%d线程%d(串行线程):所有进程的线程都已到达屏障!\n", pid, tid);
        printf("=====================================\n");
        shared_data->flag = 1; // 设置同步标志
    } else if (ret != 0) {
        fprintf(stderr, "进程%d线程%d:屏障等待失败,错误码=%d\n", pid, tid, ret);
        pthread_exit(NULL);
    }

    // 验证同步标志
    printf("进程%d线程%d:同步标志=%d,继续执行...\n", pid, tid, shared_data->flag);
    return NULL;
}

// 进程函数:创建线程并执行
void proc_func()
{
    pthread_t tid[THREAD_NUM_PER_PROC];
    int tid_arr[THREAD_NUM_PER_PROC] = {1,2};

    // 创建线程
    for (int i=0; i<THREAD_NUM_PER_PROC; i++) {
        pthread_create(&tid[i], NULL, thread_func, &tid_arr[i]);
    }

    // 等待线程完成
    for (int i=0; i<THREAD_NUM_PER_PROC; i++) {
        pthread_join(tid[i], NULL);
    }
}

int main()
{
    int fd;
    // 创建共享内存(大小为SharedData)
    fd = shm_open("/my_shared_barrier", O_CREAT | O_RDWR, 0666);
    if (fd == -1) {
        perror("shm_open failed");
        return -1;
    }
    ftruncate(fd, sizeof(SharedData));

    // 映射共享内存到进程地址空间
    shared_data = (SharedData*)mmap(NULL, sizeof(SharedData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (shared_data == MAP_FAILED) {
        perror("mmap failed");
        return -1;
    }

    // 初始化跨进程屏障属性(共享属性)
    pthread_barrierattr_t attr;
    pthread_barrierattr_init(&attr);
    pthread_barrierattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);

    // 初始化屏障:总线程数=TOTAL_THREAD_NUM
    pthread_barrier_init(&shared_data->barrier, &attr, TOTAL_THREAD_NUM);
    pthread_barrierattr_destroy(&attr);

    // 初始化同步标志
    shared_data->flag = 0;

    // 创建子进程
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork failed");
        return -1;
    } else if (pid == 0) {
        // 子进程:执行线程任务
        proc_func();
        exit(0);
    }

    // 父进程:执行线程任务
    proc_func();

    // 等待子进程退出
    waitpid(pid, NULL, 0);

    // 清理资源
    pthread_barrier_destroy(&shared_data->barrier);
    munmap(shared_data, sizeof(SharedData));
    shm_unlink("/my_shared_barrier");

    printf("主线程:跨进程屏障同步完成,程序正常退出\n");
    return 0;
}

运行结果

  • • 屏障设置PTHREAD_PROCESS_SHARED属性,实现跨进程同步;
  • • 共享内存用于存储屏障,确保不同进程访问同一屏障实例;
  • • 总线程数是所有进程的线程数之和,避免计数不匹配。
进程12345线程1:开始执行任务...
进程12345线程2:开始执行任务...
进程12346线程1:开始执行任务...
进程12346线程2:开始执行任务...
进程12345线程1:任务完成,到达跨进程屏障等待...
进程12345线程2:任务完成,到达跨进程屏障等待...
进程12346线程1:任务完成,到达跨进程屏障等待...
进程12346线程2:任务完成,到达跨进程屏障等待...
=====================================
进程12346线程2(串行线程):所有进程的线程都已到达屏障!
=====================================
进程12346线程2:同步标志=1,继续执行...
进程12345线程1:同步标志=1,继续执行...
进程12345线程2:同步标志=1,继续执行...
进程12346线程1:同步标志=1,继续执行...
主线程:跨进程屏障同步完成,程序正常退出

六、pthread 屏障 的优缺点

✅ 优点(核心优势,无可替代)

  1. 1. 实现简洁:一行代码实现多线程会合,无需手动维护计数器、互斥锁、条件变量,代码量减少 80%;
  2. 2. 效率高:所有线程同时唤醒,无惊群效应,唤醒开销远低于条件变量的广播唤醒;
  3. 3. 语义清晰:屏障的「会合」语义直接匹配阶段式任务,代码可读性高,易维护;
  4. 4. 支持跨进程:设置共享属性后,可实现跨进程线程同步,适配分布式场景;
  5. 5. 串行线程机制:内置「唯一串行线程」返回值,方便执行汇总、清理等独有的逻辑;
  6. 6. 资源开销低:屏障仅维护计数器和等待队列,资源占用远低于多个条件变量。

✅ 缺点(局限性,客观认知)

  1. 1. 灵活性低:仅支持「所有线程会合」,无法实现「部分线程同步」;
  2. 2. 复用性差:标准屏障是单次触发,复用需手动销毁 / 初始化,代码冗余;
  3. 3. 线程数固定:初始化时需确定目标线程数,动态增减线程时需重新初始化;
  4. 4. 无超时机制:POSIX 标准屏障无timedwait接口,无法设置等待超时,易导致永久阻塞;
  5. 5. 取消线程风险:等待期间取消线程会导致计数异常,需额外处理;
  6. 6. 跨进程配置复杂:需结合共享内存、共享属性,配置不当易导致同步失败。

✅ 优缺点总结

✔️ 屏障的优点是压倒性的:在多线程阶段式会合场景下,是代码最简洁、效率最高的同步方案,没有任何技术能替代;

✔️ 屏障的缺点都是可规避的:通过提前确定线程数、手动重置复用、禁用线程取消,能轻松解决所有局限性;

✔️ 结论:屏障是 Linux 多线程阶段式协作「必学、必会」的同步技术,核心是「场景匹配 + 规则遵守」。


全文核心总结

  1. 1. 屏障的核心是「多线程会合」,保证一组线程在屏障点等待,全部到达后同时继续执行;
  2. 2. 防坑黄金法则:count 值等于线程数、销毁前确保无等待、复用需重新初始化、禁止等待时取消线程
  3. 3. 核心接口:初始化(barrier_init)→等待(barrier_wait)→销毁(barrier_destroy),wait 返回值需区分串行线程;
  4. 4. 最核心场景是多线程初始化 / 分块计算,其次是性能测试、跨进程协作、阶段式任务调度;
  5. 5. 优点是实现简洁、效率高、语义清晰,缺点是灵活性低、复用性差,整体瑕不掩瑜;
  6. 6. 选型原则:多线程(≥3)阶段式会合→用屏障,两个线程同步→用条件变量,资源保护→用互斥锁 / 读写锁。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-02-07 13:49:14 HTTP/2.0 GET : https://f.mffb.com.cn/a/473859.html
  2. 运行时间 : 0.109552s [ 吞吐率:9.13req/s ] 内存消耗:4,588.39kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=103a99aac865fed3c118a3c921bfe69b
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000572s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000633s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.001391s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.001041s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000481s ]
  6. SELECT * FROM `set` [ RunTime:0.001219s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000548s ]
  8. SELECT * FROM `article` WHERE `id` = 473859 LIMIT 1 [ RunTime:0.012241s ]
  9. UPDATE `article` SET `lasttime` = 1770443354 WHERE `id` = 473859 [ RunTime:0.006030s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.002624s ]
  11. SELECT * FROM `article` WHERE `id` < 473859 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000482s ]
  12. SELECT * FROM `article` WHERE `id` > 473859 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000578s ]
  13. SELECT * FROM `article` WHERE `id` < 473859 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000792s ]
  14. SELECT * FROM `article` WHERE `id` < 473859 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.008101s ]
  15. SELECT * FROM `article` WHERE `id` < 473859 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001801s ]
0.111041s