C++ 下的多线程
简单的说:线程是可被调度的最小的指令序列,线程是操作系统的一部分,不同的操作系统,对实现,和调度策略不同。
多线程的优势:
- 快速响应:比如在一个单线程程序中,如果主线程block在一个费时的任务中(比如I/O操作),整个程序会“冻结”住,无法响应外界的输出。通过将交互任务与这个费时的任务独立成两个线程可以解决这个问题。但这并不是主要的用途,因为这种情况通过non-blocking I/O和Unix signal解决,并且带来更小的副作用。
- 更好的性能:在现代计算机中,通常会有多个核心甚至多个CPU,通过多线程可以”更容易“使得多个核心并行(Parallel)执行,这里要注意,在当今的计算机中就是单线程,也会在多个核上运行,将一些没有关系的指令运行到其他的核上,提高性能。
例如在Windows中通过CreateThread()创建进程,而在linux中使用POSIX thread模型,pthread_create()创建线程,并且在编译是要加入-pthread选项来表示正在使用POSIX thread库。可见,不同操作系统有着相似的线程概念,却包含这很多不同的实现细节。因此想要进行跨平台的多线程开发,就需要一种线程库作为thread wrapper。
C++ 语言层面的多线程 thread 类
#include<iostream> #include<stdlib.h> #include<string.h> #include<string> #include<unistd.h> #include<thread> void Threadtest(int time) { std::this_thread::sleep_for(std::chrono::seconds(time)); std::cout<<"threadtest is run"<<std::endl; } int main() { std::thread t1(Threadtest,2); // 主线程阻塞,等待子线程完成 c++ 语言层面必须等待子线程 t1.join(); // t1.detach() // 分离子线程,主线程不在等待子线程 std::cout<<"main thread is done"<<std::endl; return 0; }
join 和 detach 的区别总结
- 调用
thread::join()
时,调用线程将阻塞,直到执行线程完成。基本上,这是一种可以用来知道线程何时完成的机制。当thread::join()
返回时,操作系统执行线程已经完成,并且C++thread
对象可以被销毁。 - 调用
thread::detach()
,将执行线程与thread
对象“分离”,并且不再由thread
对象表示-它们是两个独立的事物。可以销毁C++thread
对象,并且可以继续执行OS线程。如果程序需要知道该执行线程何时完成,则需要使用其他机制。不能再对该join()
对象调用thread
,因为它不再与执行线程相关联。