c++ 多线程(二)

使用类的成员函数作为 std::thread 参数

    • [1. 基本使用方法](#1. 基本使用方法)
      • [1.1 静态成员函数](#1.1 静态成员函数)
      • [1.2 非静态成员函数](#1.2 非静态成员函数)
    • [2. 详细参数传递方式](#2. 详细参数传递方式)
      • [2.1 基本语法](#2.1 基本语法)
      • [2.2 各种对象传递方式](#2.2 各种对象传递方式)
    • [3. Lambda 表达式](#3. Lambda 表达式)
    • [4. 注意事项和常见问题](#4. 注意事项和常见问题)
      • [4.1 对象生命周期管理](#4.1 对象生命周期管理)
      • [4.2 成员函数访问控制](#4.2 成员函数访问控制)
      • [4.3 带返回值的成员函数](#4.3 带返回值的成员函数)
    • [5. 最佳实践总结](#5. 最佳实践总结)

1. 基本使用方法

1.1 静态成员函数

静态成员函数与普通函数类似,可以直接作为线程参数:

cpp 复制代码
#include <iostream>
#include <thread>

class MyClass {
public:
    static void static_func(int x) {
        std::cout << "静态函数: " << x << std::endl;
    }
};

int main() {
    std::thread t(&MyClass::static_func, 10);
    t.join();
    return 0;
}

1.2 非静态成员函数

非静态成员函数需要对象实例作为上下文:

cpp 复制代码
#include <iostream>
#include <thread>

class Worker {
public:
    void process(int id) {
        std::cout << "Worker " << id << " 处理中..." << std::endl;
    }
};

int main() {
    Worker worker;
    
    // 方法1:传递对象实例
    std::thread t1(&Worker::process, &worker, 1);
    
    // 方法2:传递对象副本(需要可复制)
    std::thread t2(&Worker::process, worker, 2);
    
    t1.join();
    t2.join();
    return 0;
}

2. 详细参数传递方式

2.1 基本语法

cpp 复制代码
std::thread t(&ClassName::MemberFunction, object_instance, arg1, arg2, ...);

2.2 各种对象传递方式

cpp 复制代码
class Calculator {
public:
    void add(int a, int b) {
        std::cout << a << " + " << b << " = " << (a + b) << std::endl;
    }
};

int main() {
    Calculator calc;
    
    // 1. 传递指针(常用)
    std::thread t1(&Calculator::add, &calc, 10, 20);
    
    // 2. 传递引用(使用 std::ref)
    std::thread t2(&Calculator::add, std::ref(calc), 30, 40);
    
    // 3. 传递智能指针
    auto ptr = std::make_unique<Calculator>();
    std::thread t3(&Calculator::add, ptr.get(), 50, 60);
    
    // 4. 传递对象副本(需要可复制)
    Calculator calc2;
    std::thread t4(&Calculator::add, calc2, 70, 80);
    
    t1.join(); t2.join(); t3.join(); t4.join();
    return 0;
}

3. Lambda 表达式

cpp 复制代码
class DataProcessor {
private:
    int data_;
    
public:
    DataProcessor(int data) : data_(data) {}
    
    void complex_process() {
        // 复杂的处理逻辑
        std::cout << "处理数据: " << data_ << std::endl;
    }
};

int main() {
    DataProcessor processor(100);
    
    // 使用lambda
    std::thread t([&processor]() {
        processor.complex_process();
    });
    
    t.join();
    return 0;
}

4. 注意事项和常见问题

4.1 对象生命周期管理

cpp 复制代码
class Task {
public:
    void run() {
        std::cout << "执行任务" << std::endl;
    }
};

void problematic_example() {
    std::thread t;
    {
        Task task;  // 局部对象
        t = std::thread(&Task::run, &task);  // 危险!task很快会被销毁
    }  // task在这里被销毁
    
    t.join();  // 访问已销毁对象!
}

void safe_example() {
    // 方法1:使用动态分配
    auto task = std::make_shared<Task>();
    std::thread t(&Task::run, task);  // 共享所有权
    
    // 方法2:确保对象生命周期
    Task task2;
    std::thread t2(&Task::run, &task2);
    t2.join();  // 在task2销毁前join
    
    t.join();
}

4.2 成员函数访问控制

cpp 复制代码
class SecureClass {
private:
    void private_func() {
        std::cout << "私有函数" << std::endl;
    }
    
public:
    void public_func() {
        // 可以通过公有函数间接调用私有函数
        std::thread t(&SecureClass::private_func, this);
        t.join();
    }
    
    static void wrapper(SecureClass* obj) {
        obj->private_func();
    }
};

4.3 带返回值的成员函数

cpp 复制代码
#include <future>

class Math {
public:
    int square(int x) {
        return x * x;
    }
};

int main() {
    Math math;
    
    // 使用 std::async 获取返回值
    auto future = std::async(&Math::square, &math, 5);
    int result = future.get();
    std::cout << "结果: " << result << std::endl;
    
    return 0;
}

5. 最佳实践总结

  1. 对象生命周期管理:确保线程执行期间对象保持有效
  2. 使用智能指针 :推荐使用 std::shared_ptr 管理对象生命周期
  3. Lambda 表达式:复杂场景下使用 lambda 更灵活
  4. 异常安全:确保线程在异常情况下也能正确结束
  5. 资源清理:确保所有线程在对象销毁前 join 或 detach
cpp 复制代码
class SafeThreadHandler {
private:
    std::thread worker_;
    
    void worker_func() {
        try {
            // 工作逻辑
        } catch (...) {
            // 异常处理
        }
    }
    
public:
    SafeThreadHandler() {
        worker_ = std::thread(&SafeThreadHandler::worker_func, this);
    }
    
    ~SafeThreadHandler() {
        if (worker_.joinable()) {
            worker_.join();
        }
    }
    
    // 禁用复制
    SafeThreadHandler(const SafeThreadHandler&) = delete;
    SafeThreadHandler& operator=(const SafeThreadHandler&) = delete;
};
相关推荐
Acc1oFl4g2 小时前
详解Java反射
java·开发语言·python
海上彼尚2 小时前
Go之路 - 6.go的指针
开发语言·后端·golang
Trouvaille ~2 小时前
【Java篇】存在即不变:深刻解读String类不变的艺术
java·开发语言·javase·stringbuilder·stringbuffer·string类·字符串常量池
lemon_sjdk2 小时前
java学习——枚举类
java·开发语言·学习
珑墨2 小时前
【浏览器】页面加载原理详解
前端·javascript·c++·node.js·edge浏览器
FreeBuf_2 小时前
Next.js 发布扫描工具:检测并修复受 React2Shell 漏洞(CVE-2025-66478)影响的应用
开发语言·javascript·ecmascript
a伊雪3 小时前
c++ 引用参数
c++·算法
御形封灵3 小时前
基于原生table实现单元格合并、增删
开发语言·javascript·ecmascript
应茶茶4 小时前
从 C 到 C++:详解不定参数的两种实现方式(va_args 与参数包)
c语言·开发语言·c++