You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

链表百万级插入过慢,是否需多线程优化?求C/C++示例

多线程插入百万级链表的C/C++实现方案

我来给你梳理下多线程操作链表的核心要点,再给你两个实用的示例代码——分别对应C和C++的常用实现,都是经过验证的基础方案,你可以直接参考:

首先得明确:链表本身是非线程安全的结构,多个线程同时修改链表指针时,必须用同步机制(比如互斥锁)保护「临界区」(也就是修改链表结构的代码段),不然会出现竞态条件,导致链表断裂、数据丢失这些诡异的问题。

C语言示例(pthread + 互斥锁)

用C的pthread库搭配互斥锁实现,这是最经典的多线程同步方案:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

// 定义链表节点结构
struct Node {
    int data;
    struct Node* next;
};

// 全局链表头节点(你要求的nodeObj)
struct Node* nodeObj = NULL;
// 全局互斥锁,专门保护链表的插入/修改操作
pthread_mutex_t list_mutex;

// 每个线程执行的插入任务
void* insert_thread(void* arg) {
    int* data_arr = (int*)arg;
    const int insert_count = 100000; // 每个线程插10万条,10个线程刚好百万级

    for (int i = 0; i < insert_count; i++) {
        // 先创建新节点
        struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
        new_node->data = data_arr[i];
        new_node->next = NULL;

        // 加锁!进入临界区,这段时间只有当前线程能操作链表
        pthread_mutex_lock(&list_mutex);
        
        // 这里示例是插入到链表头部(如果要插尾部,建议额外维护一个尾指针,避免每次遍历到末尾)
        new_node->next = nodeObj;
        nodeObj = new_node;

        // 解锁!其他线程可以开始抢锁操作链表了
        pthread_mutex_unlock(&list_mutex);
    }

    return NULL;
}

int main() {
    // 初始化互斥锁
    pthread_mutex_init(&list_mutex, NULL);

    const int thread_num = 10;
    pthread_t threads[thread_num];
    int thread_data[thread_num][100000];

    // 给每个线程准备要插入的数据(这里简单生成随机数,你可以换成自己的业务数据)
    for (int i = 0; i < thread_num; i++) {
        for (int j = 0; j < 100000; j++) {
            thread_data[i][j] = rand() % 1000000;
        }
    }

    // 创建并启动所有线程
    for (int i = 0; i < thread_num; i++) {
        pthread_create(&threads[i], NULL, insert_thread, thread_data[i]);
    }

    // 等待所有线程完成插入任务
    for (int i = 0; i < thread_num; i++) {
        pthread_join(threads[i], NULL);
    }

    // 用完锁要销毁
    pthread_mutex_destroy(&list_mutex);

    // 这里可以加一段代码遍历链表,验证插入结果(比如统计节点数量)
    // ...

    return 0;
}

小提示:

  • 示例里是插头部,如果你需要插尾部,别每次遍历到最后——额外维护一个全局的struct Node* tailObj,插入时直接操作尾指针,能大幅提升效率,当然操作尾指针的时候也要用互斥锁保护。
  • 互斥锁会有一定开销,如果所有线程都抢同一把锁,效率提升可能有限。如果你的链表是有序链表,可以试试「分段锁」:把链表分成多个段,每个段用独立的锁,不同段的插入可以并行执行,效率会高很多,不过实现复杂度也会上升。

C++语言示例(std::thread + std::mutex)

用C++标准库的线程和锁实现,代码更简洁,还能借助RAII自动管理锁,避免忘记解锁的坑:

#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <cstdlib>

// 链表节点结构
struct Node {
    int data;
    Node* next;
    Node(int val) : data(val), next(nullptr) {}
};

// 全局链表头节点
Node* nodeObj = nullptr;
// 全局互斥锁
std::mutex list_mutex;

// 线程执行的插入任务
void insert_task(const std::vector<int>& data) {
    for (int val : data) {
        Node* new_node = new Node(val);

        // 使用std::lock_guard,它会在离开作用域时自动解锁,不用担心漏解锁
        std::lock_guard<std::mutex> lock(list_mutex);
        
        // 插入到链表头部
        new_node->next = nodeObj;
        nodeObj = new_node;
    }
}

int main() {
    const int thread_count = 10;
    const int per_thread_count = 100000;
    std::vector<std::thread> threads;
    std::vector<std::vector<int>> thread_datas(thread_count);

    // 准备每个线程的插入数据
    for (int i = 0; i < thread_count; i++) {
        thread_datas[i].reserve(per_thread_count);
        for (int j = 0; j < per_thread_count; j++) {
            thread_datas[i].push_back(rand() % 1000000);
        }
    }

    // 创建并启动线程
    for (int i = 0; i < thread_count; i++) {
        threads.emplace_back(insert_task, std::ref(thread_datas[i]));
    }

    // 等待所有线程完成
    for (auto& t : threads) {
        if (t.joinable()) {
            t.join();
        }
    }

    // 记得释放链表内存,避免内存泄漏
    Node* temp;
    while (nodeObj) {
        temp = nodeObj;
        nodeObj = nodeObj->next;
        delete temp;
    }

    return 0;
}

进阶优化建议:

  1. 别用全局变量:全局变量虽然方便,但不利于代码维护。可以把链表和锁封装到一个类里,比如写个ThreadSafeLinkedList类,内部包含互斥锁和节点指针,这样更符合面向对象的设计,也更安全。
  2. 细粒度锁/分段锁:如果是有序链表,按数据范围或者哈希值分段,每个段用独立的锁,不同线程处理不同分段的插入,锁竞争会大大减少,并行效率能提升一大截。
  3. 无锁链表:如果追求极致性能,可以尝试用CAS操作实现无锁链表(比如C++的std::atomic),但实现难度很高,还要处理ABA问题这些复杂场景,新手不建议一开始就碰这个。

内容的提问来源于stack exchange,提问作者NKF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:27:18