62.线程 in C++
如何进行并行化,如何让事情同时发生。
如果正常看,平时运行代码的时候都是单线程的,即只让计算机一次只做一行或者一条指令。这对于轻量的代码来说无足轻重,但是如果是繁重的代码,就会需要设备很长时间来计算,故有时将某些工作移到两个不同的执行线程,这是很有益的。
🍅操作线程
首先要把加入头文件**#include <thread>
**(thread
即为线程的意思)
创建一个线程对象:std::thread 对象名字 (一个函数指针以及其他可选的任何参数)
等待一个线程完成它的工作的方法是通过输入**worker.join()
(这里的线程名字是worker,换其他的也可以!)(join
可以看作一个命令:嘿,你能在当前线程上等待这个线程完成它的工作吗,因此会阻塞当前线程,直到另一个线程完成**)
故此,💡调用join
的目的是:在主线程上等待 工作线程 完成所有的执行之后,再继续执行主线程
#include <iostream>
#include <thread>
void DoWork() {
std::cout << "hello" << std::endl;
}
int main() {
//DoWork即是我们想要在另一个执行线程中发生的事情
std::thread worker(DoWork); //这里传入的是函数指针!!!函数作为形参都是传函数指针!!!
//一旦写完这段代码,它就会立即启动那个线程,一直运行直到我们等待他退出
worker.join(); //join函数本质上,是要等待这个线程加入进来(而线程加入又是另一个复杂的话题了)
//因为cin.get()是join语句的下一行代码,所以它不会运行,直到DoWork函数中的所有内容完成!
std::cin.get();
}
#include <iostream>
#include <thread>
static bool flag = 1;
void DoWork() {
while (flag) {
std::cout << "hello" << std::endl;
}
}
int main() {
std::thread worker(DoWork); //开启多线程操作
std::cin.get(); //此时工作线程在疯狂循环打印,而主线程此时被cin.get()阻塞
flag = 0; //如果按下回车,则会修改flag的值,间接影响到另一个线程的工作
worker.join(); //join:等待工作线程结束后,才会执行接下来的操作
std::cin.get();
}
如果是正常情况,DoWork
应该会一直循环下去,但因为这里是多线程,所以可以在另一个线程中修改工作线程的变量,来停止该线程的循环。这便是体现多线程的例子了。
而上面的例子中的线程是以最快的速度做事情的(如DoWork
),而这里多线程的问题是,如果以这般速度做事,会导致这个线程的cpu的使用率达到100%,这并不会好。所以可以让它等待个一两秒后再执行工作,这样会缓解cpu的压力
这里需要用到C++11的chrono
库
void DoWork() {
using namespace std::literals::chrono_literals; //等待时间的操作可以先using一个命名空间,因为前缀实在是太长太痛苦了
while (flag) {
std::cout << "hello" << std::endl;
std::this_thread::sleep_for(1s); //等待一秒
}
}
上面所用到的std::this_thread
,可以用它来给当前线程下达命令
多线程对于加速程序是十分有用的,线程的主要目的就是优化。但同时也可以拿多线程做一些其他的事(比如同时处理两件事,想上面的例子中不用多线程就办不到)