C++ 多线程编程之在类中使用多线程(thread)的方法

一、thread的基本用法

参见C++使用thread类多线程编程

二、类外使用多线程,访问类的成员

这几种方式,新建线程都是在类外,然后通过把友元函数或者成员函数作为thread参数。

#include <iostream>
#include <thread>
#include <vector>
using namespace std;

class Position {
public:
    Position(int xx, int yy) : _x(xx), _y(yy) {};
    int& x(){ return _x; }
    int& y(){ return _y; }

    void member_func(int i) {
        printf("member_func:%d\n", i);
        _x = 100;
    }

    friend void pointer_style(Position *p, int i);
    friend void reference_style(Position &p, int i);

private:
    int _x;
    int _y;
};

//! 友元函数,通过指针来传递类的实例
void pointer_style(Position *p, int i) {
    printf("pointer_style:%d(%d,%d)\n", i, p->_x, p->_y);
    p->_x = 200;
}

//! 友元函数,通过引用来访问类的实例
void reference_style(Position &p, int i) {
    printf("reference_style:%d(%d,%d)\n", i, p._x, p._y);
    p._x = 300;
}

int main() {
    Position p(1, 2);

    /**
     * 1、使用类的成员函数作为子线程的参数
     * 参数说明://参数1是成员函数的指针,参数2是Position对象值传递,
     * 子线程中对p的修改不会影响主线程中的对象p。
     */

    thread t1(&Position::member_func, p, 233);
    t1.join();
    cout << "p.x=" << p.x() << endl;

    /**
     * 2、使用类的友元函数作为参数
     * 友元函数参见:https://blog.csdn.net/mary19920410/article/details/70036878
     * 参数说明:参数1是Position的友元函数reference_style,参数2是用ref包装过的引用,
     * 参数3是传给reference_style函数的值。
     * 在这种方式中,由于p是以引用的方式传递给子线程,在子线程中对p的修改相当于修改主线程中的p。
     */
    std::thread t2(reference_style, ref(p), 1);
    t2.join();
    cout << "p.x=" << p.x() << endl;

    /**
     * 3、使用类的友元函数作为参数
     * 参数说明:参数1是Position的友元函数pointer_style,参数2是p的指针,参数3是传给
     * pointer_style的参数。
     * 在这种方式中,由于p是以引用的方式传递给子线程,在子线程中对p的修改相当于修改主线程中的p。
     */
    std::thread t3(pointer_style, &p, 1);
    t3.join();
    cout << "p.x=" << p.x() << endl;

    /**
     * 4、通过lambda传递引用参数
     * 关于lambda函数的说明:https://blog.csdn.net/u010984552/article/details/53634513
     */
    auto lambda_func = [&p](int i) -> void {
        printf("lambda_func:%d(%d,%d)\n", i, p.x(), p.y());
        p.x() = 400;
    };
    /**
     * 参数说明:参数1是lambda表达式,参数2是传递给lambda表达式的参数
     * 由于在lambda_func是以引用的方式捕获p,所以在子线程中p是主线程中p的引用,在子线程中修改p
     * 相当于主线程修改主县城中的p。也可以以值传递的方式捕获p,这样在子线程中修改p就不会影响到主
     * 线程中的p。
     */
    thread t4(lambda_func, 123);
    t4.join();
    cout << "p.x=" << p.x() << endl;
    return 0;
}

三、类内使用多线程,访问类的成员

这种方法是把lambda函数(参考链接)作为线程参数,使用lambda函数捕获类的成员函数及属性,然后就可以在类内使用多线程。

#include <iostream>
#include <thread>
#include <vector>
using namespace std;

class M{
private:
    vector<int> numbers;
    vector<thread> ts;
public:
    /**
     * 构造函数
     * @param thread_count 线程数量
     */
    M(const int thread_count){
        numbers.resize(thread_count); // 调整数字容量
        //! 定义lambda函数,捕获类的成员和变量,作为thread的参数,
        //! 这样,就可以在子线程里访问类的成员。
        auto lambda_fun = [&](int i) -> void {
            this->numbers[i] = i;

            for(int j=0;j<10000;j++);
        };

        //! 创建线程
        for(int i=0;i<thread_count;i++){
            ts.push_back(thread(lambda_fun,i));
        }
        //! 等待子线程结束
        for(int i=0;i<thread_count;i++){
            ts[i].join();
        }
        //! 打印结果
        for(int i=0;i<thread_count;i++){
            printf("numbers[%d]=%d\n", i, this->numbers[i]);
        }
    }
};

int main(){
    M m(12);
    return 0;
}

 

  • 12
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值