c++ 多线程需要包含thread头文件
#include <thread>std::thread t(function_name, args...);
多线程调用函数代码如下
#include <iostream>
#include <thread>
void print_message()
{
std::cout << "Hello, world!" << std::endl;
}
int main()
{
std::thread t(print_message);
t.join();
return 0;
}
子线程和主线程同时执行,当子线程没执行完,主线程结束时,程序就会报错
join,主线程等待子线程执行完成后再执行,只能使用一次
detach,主程序结束,子线程会在后台执行
joinable,判断线程是否可以调用join和detach
//当子线程没有执行完时,主线程会阻塞在join()位置
bool isJoin = thread.joinable()
if(isJoin)
{
thread.join()// 让主线程等待子线程
}
note:
1、右值传递给左值引用会报错可以使用std::ref ,右值引用
2、多线程中传递的指针可能存在被释放的问题需要注意
3、线程安全,多线程的运行程序和单线程的运行结果都是一样的
实现线程安全可以使用互斥锁、信号量、条件变量等操作
//互斥锁
std::mutex mtx;
mtx.lock();
//...
mtx.unlock();
lock_gurad,只在局部作用域中使用,不能复制和移动,轻量级锁
unqiue_lock,重量级锁,可以手动加锁、延迟加锁
手写实现一个线程池文章来源:https://www.toymoban.com/news/detail-806749.html
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
#include <queue>
#include <vector>
#include <functional>
#include <condition_variable>
class ThreadPool {
public:
ThreadPool(int numTread) : stop(false)
{
for (int i = 0; i < numTread; i++)
{
threads.emplace_back([this]
{
while (1)
{
std::unique_lock<std::mutex> lock(mtx);
condition.wait(lock, [this]
{
return !tasks.empty() || stop;
});
if (stop && tasks.empty())
{
return;
}
std::function<void()> task(std::move(tasks.front()));
tasks.pop();
lock.unlock();
task();
}
});
}
}
~ThreadPool()
{
{
std::unique_lock<std::mutex> lock(mtx);
stop = true;
}
condition.notify_all();
for (auto& t : threads)
{
t.join();
}
}
template<class F,class ... Args>
void enqueue(F&& f, Args&& ... args)
{
std::function<void()> task =
std::bind(std::forward<F>(f), std::forward<Args>(args)...);
{
std::unique_lock<std::mutex> lock(mtx);
tasks.emplace(std::move(task));
}
condition.notify_one();
}
private:
bool stop;
std::condition_variable condition;
std::mutex mtx;
std::vector < std::thread > threads;
std::queue < std::function<void()>> tasks;
};
int main()
{
// 创建一个线程池,里面包含4个线程
ThreadPool pool(4);
// 4个线程执行10个任务
for (int i = 0; i < 10; i++)
{
// 往线程池里加任务
pool.enqueue([i]()
{
std::cout << "task : " << i << " is runing " << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "task : " << i << " is done " << std::endl;
}
);
}
return 0;
}
参考资料
1、http://www.seestudy.cn/?list_9/31.html文章来源地址https://www.toymoban.com/news/detail-806749.html
到了这里,关于C++ 多线程编程和线程池的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!