线程的任务函数可以是普通函数、类的非静态成员函数、类的静态成员函数、lambda函数、仿函数

发布时间 2023-03-29 22:27:10作者: 好人~

参考:b站视频

线程的任务函数可以是普通函数、类的非静态成员函数、类的静态成员函数、lambda函数、仿函数。下面举例说明:

#include <unistd.h>
#include <iostream>
#include <thread>  // 线程类头文件。
using namespace std;

// 普通函数。
void func(int bh, const string& str) {
  for (int ii = 1; ii <= 10; ii++) {
    cout << "第" << ii << "次表白:亲爱的" << bh << "号," << str << endl;
    sleep(1);  // 休眠1秒。
  }
}

// 仿函数。
class mythread1 {
 public:
  void operator()(int bh, const string& str) {
    for (int ii = 1; ii <= 10; ii++) {
      cout << "第" << ii << "次表白:亲爱的" << bh << "号," << str << endl;
      sleep(1);  // 休眠1秒。
    }
  }
};

// 类中有静态成员函数。
class mythread2 {
 public:
  static void func(int bh, const string& str) {
    for (int ii = 1; ii <= 10; ii++) {
      cout << "第" << ii << "次表白:亲爱的" << bh << "号," << str << endl;
      sleep(1);  // 休眠1秒。
    }
  }
};

// 类中有普通成员函数。
class mythread3 {
 public:
  void func(int bh, const string& str) {
    for (int ii = 1; ii <= 10; ii++) {
      cout << "第" << ii << "次表白:亲爱的" << bh << "号," << str << endl;
      sleep(1);  // 休眠1秒。
    }
  }
};

int main() {
  // 用普通函数创建线程。
  // thread t1(func, 3, "我是一只傻傻鸟。");
  // thread t2(func, 8, "我有一只小小鸟。");

  // 用lambda函数创建线程。
  auto f = [](int bh, const string& str) {
    for (int ii = 1; ii <= 10; ii++) {
      cout << "第" << ii << "次表白:亲爱的" << bh << "号," << str << endl;
      sleep(1);  // 休眠1秒。
    }
  };
  // thread t3(f, 3, "我是一只傻傻鸟。");

  // 用仿函数创建线程。
  // thread t4(mythread1(), 3, "我是一只傻傻鸟。");

  // 用类的静态成员函数创建线程。
  // thread t5(mythread2::func, 3, "我是一只傻傻鸟。");

  // 用类的普通成员函数创建线程。
  mythread3 myth;  // 必须先创建类的对象,必须保证对象的生命周期比子线程要长。
  thread t6(
      &mythread3::func, &myth, 3,
      "我是一只傻傻鸟。");  // 第二个参数必须填对象的this指针,否则会拷贝对象。

  cout << "任务开始。\n";
  for (int ii = 0; ii < 10; ii++) {
    cout << "执行任务中......\n";
    sleep(1);  // 假设执行任务需要时间。
  }
  cout << "任务完成。\n";

  // t1.join();         // 回收线程t1的资源。
  // t2.join();         // 回收线程t2的资源。
  // t3.join();         // 回收线程t3的资源。
  // t4.join();         // 回收线程t4的资源。
  // t5.join();         // 回收线程t5的资源。
  t6.join();  // 回收线程t6的资源。
}

【注】线程不能拷贝,但是可以将线程的资源所有权转移给新创建的线程对象。