## 第一关:威胁建模——让 AI 在写代码前先“过一遍雷”

绝大多数人让 DeepSeek 写线程池,张口就是“给我一个 Qt 线程池示例”。这等于让一个实习生不画图纸直接焊电路板。正确的姿势是:先给 AI 喂一份「威胁清单」,逼它把潜在风险写进代码注释里。

```cpp
// 威胁模型:QThreadPool 全局实例 vs 局部实例
// 风险点1:局部 QThreadPool 析构时,若任务未执行完,直接崩溃
// 风险点2:任务回调中操作 QWidget,跨线程导致 UI 卡死
// 风险点3:共享数据无锁保护,或锁粒度过大导致性能断崖

void Worker::startTask() {
    // 正确做法:使用 QThreadPool::globalInstance() 并设置过期时间
    QThreadPool *pool = QThreadPool::globalInstance();
    pool->setExpiryTimeout(30000); // 30秒无任务则回收线程

    // 错误做法:在栈上创建 QThreadPool
    // QThreadPool localPool; // 函数结束 pool 销毁,正在跑的任务直接崩
}

```

我让 DeepSeek 根据这三条风险生成代码,它自动加了 `QRunnable` 的 `autoDelete()` 处理,还主动提出用 `QFutureWatcher` 来监控任务状态。这不是魔法,是你把约束条件写清楚后,模型在概率上更倾向于生成“见过很多次的正确模式”。

**坑点提醒**:如果你让 AI 直接写“线程池操作 QLabel 文本”,它大概率会给你一个裸指针传递。必须明确告知:“所有跨线程的 UI 操作必须通过信号槽队列连接,禁止直接调用。”否则上线后你会遭遇间歇性重绘闪烁,定位到你怀疑人生。

## 第二关:代码审查——让 AI 当你的“结对队友”而非“代码生成器”

生成完代码不是结束,是开始。我习惯把 DeepSeek 生成的代码原封不动丢进一个“审查提示词”里,让它从三个维度挑刺:内存安全、竞争条件、异常路径。这一步能揪出 80% 的隐患。

```cpp
// DeepSeek 第一版生成代码(有坑)
void DataProcessor::process() {
    QList<int> data = fetchData(); // 耗时操作
    QtConcurrent::run([this, data]() {
        for (int val : data) {
            emit progressUpdated(val); // 风险:跨线程发射信号,但接收者可能已销毁
        }
    });
}

```

我把上面这段贴给它,加上提示:“请审查此代码在窗口关闭时的行为。”它指出了 `this` 指针悬挂问题,并建议改用 `QPointer` 保护:

```cpp
// 审查后修正版本
void DataProcessor::process() {
    QList<int> data = fetchData();
    QPointer<DataProcessor> guard(this);
    QtConcurrent::run([guard, data]() {
        if (!guard) return;
        for (int val : data) {
            emit guard->progressUpdated(val);
        }
    });
}

```

**坑点提醒**:审查时一定要指定“运行时场景”,比如“用户在任务执行中点击取消按钮”。泛泛而谈的“检查一下”只会让 AI 给你回一堆教科书理论,对现场毫无帮助。

## 第三关:压力测试——模拟 7x24 小时拉扯,让隐性 BUG 现形

别信“单元测试通过就没事”的鬼话。线程池的崩溃往往在 100 并发、内存碎片化、任务耗时抖动时出现。我用一个简单但致命的测试:在循环里创建 5000 个任务,随机 sleep 1~50ms,然后观察线程池是否泄漏、崩溃。

```cpp
// 压力测试代码:模拟产线高频调用
void StressTest::run() {
    QThreadPool *pool = QThreadPool::globalInstance();
    pool->setMaxThreadCount(8);

    // 启动 5000 个任务,每个任务内部随机 sleep
    for (int i = 0; i < 5000; ++i) {
        QRunnable *task = QRunnable::create([i]() {
            QThread::msleep(QRandomGenerator::global()->bounded(1, 50));
            // 模拟实际工作:写日志、更新计数器
        });
        task->setAutoDelete(true);
        pool->start(task);
    }

    // 每 500ms 检查一次线程池活跃线程数
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, [pool]() {
        qDebug() << "Active threads:" << pool->activeThreadCount();
    });
    timer->start(500);
}

```

这个测试跑了 2 小时,在 3000 次循环时复现了一个偶发崩溃:`QThreadPool: Destroyed while threads are still running`。原因是有个任务内部又调用了 `pool->start()` 导致嵌套任务,局部 `QThreadPool` 实例被提前销毁。

**坑点提醒**:压力测试必须包括“任务内部再派生子任务”的场景。很多人忽略了这一点,直到产线高峰期才炸
 

更多推荐