c++并发编程实战-第2章 线程管控
explicit thread(_Fn&& _Fx, _Args&&... _Ax); //_Fx:可调用对象 //_Ax:传递给可调用对象的参数包
1 void do_some_work(int nVal); 2 3 int a = 10; 4 std::thread my_thread(do_some_work, a);
1 class someWork 2 { 3 public: 4 void operator()()const 5 { 6 do_some_work(); 7 } 8 }; 9 10 someWork sw; 11 std::thread my_thread(sw);
1 std::thread my_thread(someWork());
1 void func(int(x), int()) 2 { 3 std::cout << x << " : " /*<< y */<< std::endl; 4 } 5 6 int test() { return 10; } 7 8 int main() 9 { 10 func(10, test); 11 }
1 std::thread my_thread{someWork()}; //初始化列表 2 std::thread my_thread((someWork())); //多加一对括号
1 auto cbk = [](){ do_some_work(); }; 2 std::thread my_thread(cbk);
1 class ThreadEntry 2 { 3 public: 4 void Process_some_data(int x) 5 { 6 cout << "thread_id : " << this_thread::get_id() << endl; 7 } 8 }; 9 10 int main() 11 { 12 cout << "main thread id : " << this_thread::get_id() << endl; 13 ThreadEntry entry; 14 std::thread th(&ThreadEntry::Process_some_data, &entry, 20); 15 th.join(); 16 }
1 th.join(); //等待 2 th.detach(); //分离
1 void do_some_work() 2 { 3 std::cout << "do_some_work start" << std::endl; 4 std::this_thread::sleep_for(std::chrono::seconds(3)); 5 std::cout << "do_some_work end" << std::endl; 6 } 7 8 int main() 9 { 10 std::thread th(do_some_work); 11 std::cout << "main start" << std::endl; 12 th.join(); //会等待子线程入口函数返回后该函数才返回 13 std::cout << "main end" << std::endl; 14 }
main start
do_some_work start
do_some_work end
main end
1 class thread_guard 2 { 3 public: 4 explicit thread_guard(std::thread& th) : m_th(th) {} 5 ~thread_guard() 6 { 7 if (m_th.joinable()) //避免多次调用join 8 m_th.join(); 9 } 10 thread_guard(const thread_guard&) = delete; 11 thread_guard& operator=(const thread_guard&) = delete; 12 13 private: 14 std::thread& m_th; 15 };
1 void threadEntry(int* pData) 2 { 3 ... 4 } 5 6 void func() 7 { 8 int nLocalData = 0; 9 std::thread th(threadEntry(&nLocalData)); 10 thread_guard(th); 11 do_something_in_current_thread(); //该函数可能导致异常 12 }
1 class ThreadOperator 2 { 3 public: 4 ThreadOperator(int& nData) : m_nData(nData) {} 5 void operator()() 6 { 7 do_some_work(m_nData); //对象的引用,可能该对象已经被销毁 8 } 9 private: 10 int& m_nData; 11 }; 12 13 void func() 14 { 15 int nLocalData = 0; 16 ThreadOperator op(nLocalData); 17 std::thread th(op); 18 th.detach(); //不等待线程结束 19 }
1 ThreadOperator(int nData) : m_nData(nData) {}
1 class someWork 2 { 3 public: 4 void operator()(int x, double y)const 5 { 6 cout << x << " : " << y << endl; // 10 : 23.5 7 } 8 }; 9 10 int main() 11 { 12 std::thread th(someWork(), 10, 23.5); //根据参数表依次传递 13 th.join(); 14 }
参数传递流程
1 class Res_Data 2 { 3 public: 4 Res_Data() 5 { 6 cout<<"Constractor"<<endl; 7 } 8 9 ~Res_Data() 10 { 11 cout<<"Destractor"<<endl; 12 } 13 14 Res_Data(const Res_Data& ) 15 { 16 cout<<"Copy Constractor"<<endl; 17 } 18 19 Res_Data& operator=(const Res_Data&) 20 { 21 cout<<"Copy Assignment Operator"<<endl; 22 return *this; 23 } 24 25 Res_Data(Res_Data&& ) 26 { 27 cout<<"Move Constractor"<<endl; 28 } 29 30 Res_Data& operator=(Res_Data&&) 31 { 32 cout<<"Move Assignment Operator"<<endl; 33 return *this; 34 } 35 }; 36 37 void func(Res_Data data) { } 38 39 int main() 40 { 41 Res_Data data; 42 thread th(func, data); 43 th.join(); 44 cout<<"Main End"<<endl; 45 return 0; 46 }
输出:
Constractor
Copy Constractor
Move Constractor
Destractor
Destractor
Main End
Destractor
1 void func(const Res_Data& data) { }
输出:
1 Constractor 2 Copy Constractor //依旧发生了一次拷贝构造 3 Destractor 4 Main End 5 Destractor
1 thread th(func, std::ref(data));
输出:
Constractor
Main End
Destractor
1 void func(const Res_Data& data) { } //万能引用 2 void func(Res_Data&& data) { } //移动语义 3 void func(Res_Data& data) { } //error
1 void func(char* pData) 2 { 3 cout << pData << endl; //pData : 0x00effdac 4 } 5 6 int main() 7 { 8 char pBuf[] = "abcdef"; //pBuf : 0x00effdac 9 thread th(func, pBuf); 10 th.detach(); 11 }
void func(string sData) { cout << sData<< endl; } int main() { char pBuf[] = "abcdef"; thread th(func, pBuf); //pBuf会调用string的构造函数构造string对象 th.detach(); }
1 int main() 2 { 3 char pBuf[] = "abcdef"; 4 thread th(func, string(pBuf));//pBuf会调用string的构造函数构造string对象 5 th.detach(); 6 }
unique_ptr对象,该对象只支持移动,而不支持拷贝。
1 class big_obj 2 { 3 public: 4 big_obj() {} 5 void setdata(int nData) { m_nData = nData; } 6 7 void print() 8 { 9 cout << m_nData << endl; 10 } 11 12 private: 13 int m_nData = 0; 14 }; 15 16 void process_big_object(std::unique_ptr<big_obj> _ptr) 17 { 18 cout << "son thread : " << this_thread::get_id() << endl; 19 _ptr->print(); 20 } 21 22 int main() 23 { 24 cout << "main thread : " << this_thread::get_id() << endl; 25 std::unique_ptr<big_obj> pObj = std::make_unique<big_obj>(); //构造std::unique_ptr对象 26 pObj->setdata(10); 27 std::thread th(process_big_object, std::move(pObj)); //将std::unique_ptr对象传递给线程入口函数 28 th.join(); 29 }
1 void do_some_work() {} 2 void do_work(){} 3 4 std::thread th1(do_some_work); 5 std::thread th2(std::move(th1)); 6 std::thread th3; 7 th3 = std::move(th2); 8 9 std::thread th4(do_work); 10 th4 = std::move(th3); //error
1 void do_work(){} 2 3 std::thread GetThread() 4 { 5 std::thread th(do_work); 6 return th; //将该线程交由外部管理 7 } 8 9 void ProcessThread(std::thread th) //交由某个函数管理 10 { 11 if(th.joinable()) 12 th.join(); 13 }
void func() { std::vector<std::thread> vThreads; for (int i = 0; i < 10; ++i) { vThreads.emplace_back(do_work, i); } for (auto& itr : vThreads) itr.join(); }
1 template<typename Iterator, typename T> 2 struct accumulate_block 3 { 4 void operator()(Iterator first, Iterator last, T& result) 5 { 6 result = std::accumulate(first, last, 0); 7 } 8 }; 9 10 template<typename Iterator, typename T> 11 T parallel_accumulate(Iterator first, Iterator last, T init) 12 { 13 unsigned long const length = std::distance(first, last); 14 if (!length) 15 return init; 16 17 unsigned long const min_per_thread = 25; 18 unsigned long const max_thread = (length + min_per_thread - 1) / min_per_thread; 19 unsigned long const hardware_threads = std::thread::hardware_concurrency(); 20 unsigned long const num_thread = std::min(hardware_threads != 0 ? hardware_threads : 2, max_thread); 21 22 unsigned long const block_size = length / num_thread; 23 24 std::vector<T>results(num_thread); 25 std::vector<std::thread> ths(num_thread - 1); 26 Iterator block_start = first; 27 28 for (int i = 0; i < num_thread - 1; ++i) 29 { 30 Iterator block_end = block_start; 31 std::advance(block_end, block_size); 32 33 accumulate_block<Iterator, T> _block; 34 std::thread th = std::thread(_block, block_start, block_end, std::ref(results[i])); 35 ths[i] = std::move(th); 36 block_start = block_end; 37 } 38 accumulate_block<Iterator, T>()(block_start, last, std::ref(results[num_thread - 1])); 39 40 for (auto& itr : ths) 41 itr.join(); 42 43 return std::accumulate(results.begin(), results.end(), init); 44 }