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

树莓派C++线程代码运行异常,抛出未知std::system_error错误

树莓派C++线程代码运行终止异常排查

原始练习代码

// Standard C++ Libraries file, time and memory
#include <memory>
#include <fstream>
#include <chrono>
// Standard C++ Libraries for multi-threading
#include <thread>
#include <mutex>
#include <atomic>
#include <iostream>
#include <unistd.h>

using namespace std;
static mutex cout_lock;

static atomic<bool> main_done;

void func1(){
    while(1){
        sleep(1);
        cout_lock.lock();
        cout<<"In Fun1"<<"\n";
        cout_lock.unlock();
        if(main_done.load()){
            cout<<"Stopping Func1"<<"\n";
            break;
        }
    }
}

void func2(){
    while(1){
        sleep(1);
        cout_lock.lock();
        cout<<"In Fun2"<<"\n";
        cout_lock.unlock();
        if(main_done.load()){
            cout<<"Stopping Func2"<<"\n";
            break;
        }
    }
}

int main(){
    main_done.store(false);
    thread fn1(func1);
    thread fn2(func2);
    for (size_t idx = 0; idx < 5; ++idx)
    {
        cout<<idx<<"\n";
        sleep(1);
    }
    main_done.store(true);
    fn1.join();
    fn2.join();

    return 1;
}

编译与运行异常

使用以下命令编译:

g++ -Ofast -pthread thread_test.cpp -o thread_test

运行时能正常输出线程循环内容,但程序最终抛出异常:

terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1225166128
Aborted

修改后的代码及新问题

尝试用try-catch包裹main逻辑,修改后代码片段:

try{
    main_done.store(false);
    thread fn1(func1);
    thread fn2(func2);
    for (size_t idx = 0; idx < 5; ++idx)
    {
        {
            unique_lock<mutex> lockMain(cout_lock);
            cout<<idx<<"\n";
        }
        sleep(1);
    }
    main_done.store(true);
    fn1.join();
    fn2.join();
}catch(std::exception const& e){
    std::cerr << "Error: " << e.what() << '\n';
}

return 0;

运行后仍出现终止错误,输出如下:

0
In Fun1
In Fun2
1
In Fun1
In Fun2
2
In Fun1
In Fun2
3
In Fun1
In Fun2
4
In Fun1
In Fun2
terminate called without an active exception
Aborted

问题原因与解决方法

核心问题

  1. cout输出未完全加锁:线程函数中退出时的cout<<"Stopping FuncX"<<"\n";未使用互斥锁保护,多个线程同时写入标准输出会触发未定义行为,导致程序异常终止。
  2. -Ofast优化的潜在影响:-Ofast会启用激进优化(包括忽略部分C++标准规则),可能对atomic变量的内存访问逻辑产生干扰,引发线程同步问题。
  3. 循环逻辑顺序不合理:线程先执行输出再检查退出条件,导致主线程设置main_done后,线程仍会先执行一次输出,增加了竞争风险。

修复步骤

  1. 给所有cout操作加锁:使用lock_guard或unique_lock确保所有标准输出操作都受互斥锁保护,避免竞争:
    修改线程函数示例:
    void func1(){
        while(true){
            // 先检查退出条件,避免不必要的执行
            if(main_done.load(std::memory_order_acquire)){
                std::lock_guard<std::mutex> lock(cout_lock);
                std::cout<<"Stopping Func1"<<"\n";
                break;
            }
            sleep(1);
            std::lock_guard<std::mutex> lock(cout_lock);
            std::cout<<"In Fun1"<<"\n";
        }
    }
    
  2. 调整循环逻辑:先检查退出条件再执行任务,减少不必要的执行和竞争。
  3. 替换优化参数:将-Ofast改为-O2,在保证优化效果的同时遵循C++标准,避免对线程同步逻辑的破坏。
  4. 显式指定atomic内存序:对atomic变量的读写指定明确的内存序(如memory_order_acquire/memory_order_release),确保线程间的内存可见性。

完整修复后代码示例

#include <memory>
#include <fstream>
#include <chrono>
#include <thread>
#include <mutex>
#include <atomic>
#include <iostream>
#include <unistd.h>

using namespace std;
static mutex cout_lock;
static atomic<bool> main_done;

void func1(){
    while(true){
        if(main_done.load(memory_order_acquire)){
            lock_guard<mutex> lock(cout_lock);
            cout<<"Stopping Func1"<<"\n";
            break;
        }
        sleep(1);
        lock_guard<mutex> lock(cout_lock);
        cout<<"In Fun1"<<"\n";
    }
}

void func2(){
    while(true){
        if(main_done.load(memory_order_acquire)){
            lock_guard<mutex> lock(cout_lock);
            cout<<"Stopping Func2"<<"\n";
            break;
        }
        sleep(1);
        lock_guard<mutex> lock(cout_lock);
        cout<<"In Fun2"<<"\n";
    }
}

int main(){
    main_done.store(false, memory_order_release);
    thread fn1(func1);
    thread fn2(func2);
    
    for (size_t idx = 0; idx < 5; ++idx)
    {
        lock_guard<mutex> lock(cout_lock);
        cout<<idx<<"\n";
        sleep(1);
    }
    
    main_done.store(true, memory_order_release);
    fn1.join();
    fn2.join();

    return 0;
}

编译命令

g++ -O2 -pthread thread_test.cpp -o thread_test

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 14:55:13