东方耀AI技术分享
标题:
多线程比单线程的程序耗时还要多:锁用得太频繁
[打印本页]
作者:
东方耀
时间:
2021-8-9 15:50
标题:
多线程比单线程的程序耗时还要多:锁用得太频繁
多线程比单线程的程序耗时还要多:锁用得太频繁
#include <iostream>
#include <list>
#include <string>
#include <chrono>
#include <thread>
class Message
{
private:
std::string m_data;
public:
Message(std::string d);
const std::string& data();
};
Message::Message(std::string d) : m_data(d)
{
}
const std::string& Message::data(){
return m_data;
}
std::list<Message> global_message_list;
void worker(){
while(!global_message_list.empty()){
auto iter = global_message_list.begin();
//do real work and erase it!
global_message_list.erase(iter);
}
}
// 单线程编程
//real 0m11.185s
// user 0m0.186s
// sys 0m0.117s
int main(){
for(int i=0;i<10000;++i){
global_message_list.push_back("this is a test"+std::to_string(i));
}
worker();
for(int i=0;i<10000;++i){
std::this_thread::sleep_for(std::chrono::milliseconds(1));
global_message_list.push_back("the second "+std::to_string(i));
}
worker();
return 0;
}
复制代码
#include <iostream>
#include <list>
#include <vector>
#include <thread>
#include <atomic>
#include <mutex>
class Message
{
private:
std::string m_data;
public:
Message(std::string d);
const std::string& data();
};
Message::Message(std::string d) : m_data(d)
{
}
const std::string& Message::data(){
return m_data;
}
std::list<Message> global_message_list; //所有stl中的容器都是线程不安全的
std::mutex global_mutex;
std::atomic<bool> ready(false); //原子操作变量
std::atomic<bool> quit(false);
void worker(int i){
while(!ready){
//没有准备好 就在循环中等待
}
while(!quit){ // 不退出
std::lock_guard<std::mutex> lock(global_mutex); //利用lock对象的构造与自动析构
if(global_message_list.empty()){
continue;
}
auto iter = global_message_list.begin();
//do real work and erase it!
global_message_list.erase(iter);
}
}
// real 0m11.248s
// user 0m0.297s
// sys 0m0.568s
// 发现:多线程比单线程的程序耗时还要多,原因何在?
// 1、锁用得过于频繁
int main(){
// 数据的准备工作
for(int i=0;i<10000;++i){
global_message_list.push_back("this is a test"+std::to_string(i));
}
// 创建多个线程来干活
const int threadCount = 4;
std::vector<std::thread> pool;
for(int i=0;i<threadCount;i++){
//pool.emplace_back(worker, i);
// 创建线程 非lambda函数方式
pool.emplace_back(std::thread(worker, i));
}
// 主线程给 每个子线程的 一个信号(命令):准备干活了
ready = true;
// 主线程往全局list放数据
for(int i=0;i<10000;++i){
std::lock_guard<std::mutex> lock(global_mutex);
std::this_thread::sleep_for(std::chrono::milliseconds(1));
global_message_list.push_back("the second "+std::to_string(i));
}
//quit=true;
while (true)
{
std::lock_guard<std::mutex> lock(global_mutex);
if(global_message_list.empty()){
// 主线程 发信号给所有的子线程
// 假设:所有子线程是要把活 全部干完的!
quit=true;
break;
}
}
for(auto &v : pool){
if(v.joinable()){
v.join();
}
}
std::cout << "主线程结束!" << std::endl;
return 0;
}
复制代码
欢迎光临 东方耀AI技术分享 (http://ai111.vip/)
Powered by Discuz! X3.4