在C++11之前,我们要在程序中新建一个线程是很麻烦的,不过好在现在借助C++11和boost库,我们可以非常方便的以各种姿势往程序里新加几个线程了。本文为你总结了以下3种方式来新建线程:
- std::thread:c++11提供的线程类,使用它可以很容易的新建和运行一个线程
- std::async:c++11提供的创建任务的方法,是比std::thread更加高一层的工具,用它既可以创建线程,也能让标准库“智能”的帮你判断是否是新建一个线程还是延迟处
- boost::asio::thread_pool:通常在需要创建大量线程的时候,使用线程池可以避免线程的重复创建。可惜c++11没有现成的方法创建线程池,我们可以借助boost库来实现。
std::thread
```cppinclude
include
include
include
std::string GetThreadIdString(const std::thread::id& id) { std::stringstream ss; ss << id; return ss.str(); }
int Mytask(int iNum) { // 这里不使用”cout << A << B << C”而使用”cout << A + B + C”,因为前者是3个cout的步骤,多线程下容易输出混乱,而后者只有一个cout步骤 std::cout << “tid(“+ GetThreadIdString(std::this_thread::get_id()) +”) “ + “do:” + std::to_string(iNum) + “\n”; return iNum; }
//演示std::promise
void MyTask2(int iNum, std::promise
int main(int argc, char *argv[]) {
std::promise
std::thread t1(MyTask2, 1, std::ref(pr1));
std::thread t2(MyTask2, 2, std::ref(pr2));
std::thread t3(MyTask2, 3, std::ref(pr3));
std::thread t4(MyTask2, 4, std::ref(pr4));
std::thread t5(MyTask2, 5, std::ref(pr5));
std::thread t6(std::ref(task6), 6);
//t.join(); //阻塞线程池,避免main函数结束导致线程中的任务没运行
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); //阻塞main函数线程1s,给时间让线程池中的任务运行
std::cout << "rst1:" << pr1.get_future().get() << std::endl;
std::cout << "rst2:" << pr2.get_future().get() << std::endl;
std::cout << "rst3:" << pr3.get_future().get() << std::endl;
std::cout << "rst4:" << pr4.get_future().get() << std::endl;
std::cout << "rst5:" << pr5.get_future().get() << std::endl;
std::cout << "rst6:" << task6.get_future().get() << std::endl;
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
}
运行结果:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/675577/1649152764417-c4c96dda-316d-4639-8ded-33ffceecb099.png#clientId=u679589ee-d091-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=252&id=u2c0ac452&margin=%5Bobject%20Object%5D&name=image.png&originHeight=504&originWidth=1436&originalType=binary&ratio=1&rotation=0&showTitle=false&size=71388&status=done&style=none&taskId=udf6cfaa5-c87b-4113-aefc-0f42ffc4619&title=&width=718)
<a name="oKJXy"></a>
## std::async
```cpp
#include <iostream>
#include <thread>
#include <future>
#include <sstream>
std::string GetThreadIdString(const std::thread::id& id)
{
std::stringstream ss;
ss << id;
return ss.str();
}
int Mytask(int iNum)
{
// 这里不使用"cout << A << B << C"而使用"cout << A + B + C",因为前者是3个cout的步骤,多线程下容易输出混乱,而后者只有一个cout步骤
std::cout << "tid("+ GetThreadIdString(std::this_thread::get_id()) +") " + "do:" + std::to_string(iNum) + "\n";
return iNum;
}
int main(int argc, char *argv[]) {
std::future<int> fut1 = std::async(std::launch::async, Mytask, 1);
std::future<int> fut2 = std::async(std::launch::async, Mytask, 2);
std::future<int> fut3 = std::async(std::launch::async, Mytask, 3);
std::future<int> fut4 = std::async(std::launch::async, Mytask, 4);
std::future<int> fut5 = std::async(std::launch::async, Mytask, 5);
std::future<int> fut6 = std::async(std::launch::async, Mytask, 6);
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); //阻塞main函数线程1s,给时间让线程池中的任务运行
std::cout << "rst1:" << fut1.get() << std::endl;
std::cout << "rst2:" << fut2.get() << std::endl;
std::cout << "rst3:" << fut3.get() << std::endl;
std::cout << "rst4:" << fut4.get() << std::endl;
std::cout << "rst5:" << fut5.get() << std::endl;
std::cout << "rst6:" << fut6.get() << std::endl;
}
boost::asio::thread_pool
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/thread_pool.hpp>
#include <thread>
#include <sstream>
std::string GetThreadIdString(const std::thread::id& id)
{
std::stringstream ss;
ss << id;
return ss.str();
}
int MyTask(int iNum)
{
// 这里不使用"cout << A << B << C"而使用"cout << A + B + C",因为前者是3个cout的步骤,多线程下容易输出混乱,而后者只有一个cout步骤
std::cout << "tid("+ GetThreadIdString(std::this_thread::get_id()) +") " + "do:" + std::to_string(iNum) + "\n";
return iNum;
}
int main(int argc, char *argv[]) {
boost::asio::thread_pool pool(4); //4线程的线程池
//陆续将任务塞入线程池
boost::asio::post(pool, std::bind(MyTask, 1));
boost::asio::post(pool, std::bind(MyTask, 2));
boost::asio::post(pool, std::bind(MyTask, 3));
boost::asio::post(pool, std::bind(MyTask, 4));
boost::asio::post(pool, std::bind(MyTask, 5));
boost::asio::post(pool, std::bind(MyTask, 6));
boost::asio::post(pool, std::bind(MyTask, 7));
boost::asio::post(pool, std::bind(MyTask, 8));
boost::asio::post(pool, std::bind(MyTask, 9));
boost::asio::post(pool, std::bind(MyTask, 10));
//pool.join(); //阻塞线程池,避免main函数结束导致线程中的任务没运行
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); //阻塞main函数线程1s,给时间让线程池中的任务运行
pool.join();
}
运行结果: