c++11 多线程传参问题

本文探讨了如何在C++中通过全局函数和类对象作为线程参数,并揭示了不同类型的参数传递(值引用、指针、字符串和临时对象)对线程行为的影响。特别强调了引用与值传递的区别,以及如何正确使用string引用以避免内存共享问题。
摘要由CSDN通过智能技术生成

1、全局函数作为线程参数传递

/**
 *  mySonThread 线程执行函数
 */
int mySonThread()
{
    cout << "子线程:开始" << endl;
    for (int i = 0; i < 10; i++) {
        cout << "子线程执行第:" << i << " 次" << endl;
    }
    cout << "子线程结束" << endl;
    return 0;
}

void example1()
{
    thread thread1(mySonThread); //创建线程,线程起点是mySonThread
    thread1.join();
}

2、类对象作为线程参数传递

/**
 * 用类对象创建线程
 */
class SonTheardClass
{
public:
    SonTheardClass(int i) : num(i)
    {
        cout << "构造函数被执行,线程ID:" << this_thread::get_id() << endl;
    }
    SonTheardClass(const SonTheardClass &mysonthread) : num(mysonthread.num)
    {
        cout << "拷贝构造被执行,线程ID:" << this_thread::get_id() << endl;
    }
    void operator()() //不能带参数
    {
        cout << "mySonTheardClass is begining!" << endl;
        cout << "作为类参数对象被执行,线程ID:" << this_thread::get_id()
             << endl;
        cout << "mySonTheardClass is over!" << endl;
    }
    ~SonTheardClass()
    {
        cout << "析构被执行,线程ID" << this_thread::get_id() << endl;
    }

public:
    int num;
};
void example2()
{
    SonTheardClass mySonTheardClass(6);
    thread thread2(mySonTheardClass);
    thread2.join();
}

3、传参问题

  • 传递值引用时:可以观察到addr_i_thread与addr_i所表示的地址不一样,因此可以断定,当线程中即使传入引用,其实并不是真实的引用,也是值传递,因为将i又额外的复制了一份存入到不同的地址中,当主线程结束,不会影响子线程
  • 传递指针时: 可以观察到,当线程传入字符串指针时,addr_buff_thread与addr_buff一致,也就是说两个线程共用一个内存,如果主线程结束,那么子线程就会出现错误
  • 传递字符串时:可以观察到当传入string引用时,则addr_buff_thread与addr_buff不一致,也就是两个线程没有共用一个内存;如果采用值传递的方式,则会发现addr_buff_thread与addr_buff是一致的,说明两个线程公用一个内存。因此,使用线程在传字符串时,要使用string&;
  • 传递临时对象时:要保证当线程使用这个临时对象时,主线程没有将它回收。
#include <iostream>
#include <unistd.h>
#include <thread>
#include "stdio.h"
#include <string>
using namespace std;

void mytempthread(const int &i, char *buff1, const string &buff2)
{
    cout << "mytempthread is begining!" << endl;

    cout << "i= " << i << endl;
    const int *addr_i_thread = &i;
    cout
        << "addr_i_thread= " << addr_i_thread
        << endl; 

    printf(
        "addr_buff_pointer_thread= %lx\n",
        buff1);
    printf(
        "addr_buff_ref_thread= %lx\n",
        &buff2); 

    cout << "mytempthread is over!" << endl;
}

void example3()
{
    int i = 2;
    const int *addr_i = &i;
    cout << "addr_i= " << addr_i << endl;
    char buff[] = "temp buff";
    cout << "addr_buff= " << &buff << endl;
    // thread3(mytempthread,i,buff,buff);//注意第三个参数时什么时候转换成string的
    //事实上有可能主线程buff已经被回收了,子线程才用到这个buff,才开始转换。
    thread thread3(
        mytempthread, i, buff,
        string(
            buff)); //传递临时对象做为线程参数,注意参数3,应该在此处进行转换。
    thread3.join();
}

int main(int argc, char *argv[])
{
    cout << "主线程:开始"
         << endl; //主线程是从main函数开始执行,执行到return ,主线程结束
    example3();
    cout << "主线程:结束" << endl;
    return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值