C++ 併發編程(一):建立線程

這個系列是我近期學習 C++ 併發編程的總結,文章和代碼最初都是基於 Boost.Thread,可是最近愈來愈發現,STL 內置的線程和同步工具已經足夠完善了。ios

STL 和 Boost 線程,在設計和用法上極其類似,一旦掌握了一個,不難切換到另外一個。若是非要比較的話,Boost 更完善一些,好比 Boost 提供了 thread_groupupgrade_lock,STL 則沒有。編程

此節介紹「線程的建立」。併發

Hello 1

經過一個不帶參數的函數建立線程。函數

#include <iostream>
#include <thread>

void Hello() {
  // 睡眠一秒以模擬數據處理。
  std::this_thread::sleep_for(std::chrono::seconds(1));
  std::cout << "Hello, World!" << std::endl;
}

int main() {
  // 建立一個線程對象,注意函數 Hello 將當即運行。
  std::thread t(&Hello);

  // 等待線程結束。
  // 不然線程還沒執行(完),主程序就已經結束了。
  t.join();

  return 0;
}

Hello 2

經過一個帶參數的函數建立線程。工具

#include <iostream>
#include <thread>

void Hello(const char* what) {
  // 睡眠一秒以模擬數據處理。
  std::this_thread::sleep_for(std::chrono::seconds(1));
  std::cout << "Hello, " << what << "!" << std::endl;
}

int main() {
  std::thread t(&Hello, "World");
  
  // 等價於使用 bind:
  //   std::thread t(std::bind(&Hello, "World"));

  t.join();

  return 0;
}

Hello 3

經過一個函數對象——即仿函數(functor)——建立線程。學習

#include <iostream>
#include <thread>

class Hello {
public:
  void operator()(const char* what) {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Hello, " << what << "!" << std::endl;
  }
};

int main() {
  Hello hello;

  // 方式一:拷貝函數對象。
  std::thread t1(hello, "World");
  t1.join();

  // 方式二:不拷貝函數對象,經過 boost::ref 傳入引用。
  // 用戶必須保證被線程引用的函數對象,擁有超出線程的生命期。
  // 好比這裏經過 join 線程保證了這一點。 
  std::thread t2(std::ref(hello), "World");
  t2.

  return 0;
}

Hello 4

經過一個成員函數建立線程。
與前例不一樣之處在於,須要以 bind 綁定 this 指針做爲第一個參數。this

#include <iostream>
#include <thread>

class Hello {
public:
  Hello() {
    std::thread t(std::bind(&Hello::Entry, this, "World"));
    t.join();
  }

private:
  // 線程函數
  void Entry(const char* what) {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Hello, " << what << "!" << std::endl;
  }
};

int main() {
  Hello hello;
  return 0;
}

Counter

建立兩個線程,各自倒着計數。
此例順帶演示了 detached 線程,被 detached 的線程,自生自滅,不受控制,沒法再 join。線程

#include <iostream>
#include <thread>

class Counter {
public:
  Counter(int value) : value_(value) {
  }

  void operator()() {
    while (value_ > 0) {
      std::cout << value_ << " ";
      --value_;
      std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    std::cout << std::endl;
  }

private:
  int value_;
};

int main() {
  std::thread t1(Counter(3));
  t1.join();

  std::thread t2(Counter(3));
  t2.detach();

  // 等待幾秒,否則 t2 根本沒機會執行。
  std::this_thread::sleep_for(std::chrono::seconds(4));
  
  return 0;
}
相關文章
相關標籤/搜索