c++ 学习之 多线程(二) thread的参数传递

c++ 学习之 多线程(二) thread的参数传递

前言

上一篇文章中讲了thread的四种构造函数,接下来给大家讲一讲thread的参数传递。

正文

1.初始化构造函数
利用初始化构造函数创建对象,第一个位置必须要传入一个可调用对象。c++ 中的可调用对象大概有这么几种:普通函数 ,类成员函数,类静态函数,仿函数,函数指针,lambda表达式,std::function。不了解可调用对象的可以戳这里,我写的另一篇关于可调用对象的文章。
(1)普通函数
用普通函数来初始化thread对象很简单,只需要把函数名传进去即可,函数中的参数按照顺序传入:

#include<stdio.h>
#include<thread>
void fun(int a,int b)
{
    printf("%d\n",a+b);
}
int main()
{
    int a =1;
    int b =2;
    std::thread t(fun,a,b);
    t.join();
}

输出结果为 : 3

(2)类成员函数
类成员函数是有真正地址的,利用 &类名::函数名 可以拿到成员函数的地址。注意,最好先创建一个了类对象,不建议用临时对象。第二位参数传入该对象。

#include<stdio.h>
#include<thread>
class A
{
  public:
  void fun(int a,int b)
  {
     printf("%d\n",a+b);
  }
};
int main()
{
     int a =1;
     int b =2;
     A c;
     std::thread t(&A::fun,c,a,b);
     t.join();
}

输出结果为 : 3
(3)类静态成员函数
类静态成员函数不需要指定类对象。

#include<stdio.h>
#include<thread>
class A
{
  public:
  static void fun(int a,int b)
  {
     printf("%d\n",a+b);
  }
};
int main()
{
     int a =1;
     int b =2;
     std::thread t(&A::fun,a,b);
     t.join();
}

输出结果为: 3

(4) 仿函数(即用类对象创建线程)
仿函数是使用类来模拟函数调用行为,我们只要重载一个类的operator()方法,即可像调用一个函数一样调用类。这种方式用得比较少。

#include<stdio.h>
#include<thread>
class A
{
 public:
  void operator()(int a,int b)//实现了对()的重载
  {
     printf("%d\n",a+b);
  }
};
int main()
{
   int a =1;
   int b =2;
   A c;
   std::thread t(c,a,b);
   t.join();
}

输出结果为 : 3
我们只需要在类的内部对() 进行重载,然后就可以将该类的对象作为可调用对象初始化thread。

(5)函数指针
没啥说的,函数指针的使用,和回调函数用法差不多。

#include<stdio.h>
#include<thread>
void fun(int a, int b)
{
 printf("%d\n", a + b);
}
int main()
{
	 int a = 1;
	 int b = 2;
	 void (*p)(int, int) = fun;
	 std::thread t(p, a, b);
	 t.join();
}

输出结果为 : 3
(6)lambda表达式

将匿名函数作为可调用对象创建thread。

扫描二维码关注公众号,回复: 10372306 查看本文章
#include<stdio.h>
#include<thread>
int main()
{
 int a = 1;
 int b = 2;
 auto c = [](int a, int b) {printf("%d\n", a + b); };
 std::thread t(c, a, b);
 t.join();
 
}

输出结果为 : 3

(7) std::function
std::function 可以用来描述C++中的可调用实体,它可以兼容所有可调用对象,自然也可以通过它来初始化thread对象。

#include<stdio.h>
#include<thread>
#include<functional>
std::function<void(int, int)> Function;

//普通函数
void fun(int a,int b)
{
 printf("普通函数:%d\n", a + b);
}
void fun2(int a, int b)
{
 printf("函数指针:%d\n", a + b);
}

class A
{
public:
 //类成员函数
 void fun1(int a, int b)
 {
  printf("类成员函数:%d\n", a + b);
 }
 //静态成员函数
 static void fun2(int a, int b)
 {
  printf("静态成员函数:%d\n", a + b);
 }
 //仿函数
 void operator ()(int a, int b)
 {
  printf("仿函数(类对象):%d\n", a + b);
 }
};
int main()
{
 int a = 1;
 int b = 2;
 
 //lambda表达式
 auto lam = [](int a, int b) {printf("lambda表达式:%d\n", a + b); };
 Function = lam;
 std::thread t1(Function, a, b);
 t1.join();
 
 //函数指针
 void(*p)(int, int) = fun2;
 Function = p;
 t1 = std::thread(Function, a, b);
 t1.join();
 
 //静态成员函数
 Function = &A::fun2;
 t1 = std::thread(Function, a, b);
 t1.join();
 
 //成员函数
 A c;
 Function = std::bind(&A::fun1,c, std::placeholders::_1, std::placeholders::_2);// 此时将对象c指定为对象实例
 t1 = std::thread(Function,a,b);// 这里不用将c传进去了
 t1.join();
 
 //仿函数
 A d;
 Function = d;
 t1 = std::thread(Function, a, b);
 t1.join();
 }

输出结果:
lambda表达式:3
函数指针:3
静态成员函数:3
类成员函数:3
仿函数(类对象):3

可以用到的初始化的方式大概就这样几种,都得用到可调用对象。

2.移动构造函数
首先我们要明白移动构造函数的用途,是把一个thread对象的线程转移到构造出来的thread对象上,可以通俗的理解成一次性赋值,过后被移动的thread对象将不在执行线程。但是我们不也能直接将被移动thread对象作为参数传进去,需要用std::move(),将它转换为右值

#include<stdio.h>
#include<thread>
void fun()
{
 printf("I love China\n");
}
int main()
{
 std::thread t(fun);
 std::thread t1(std::move(t));
 t1.join();
}
发布了10 篇原创文章 · 获赞 6 · 访问量 415

猜你喜欢

转载自blog.csdn.net/weixin_45074185/article/details/104373940
今日推荐