C++多线程编程(二)
多线程是程序员必须掌握的一门技术,本文主要是针对于C++新标准中多线程库,需要具备一定C++基础方可学习。
本章节是C++多线程编程第二课,C++不熟悉的可以转接C++专辑教程,本章节主要讲解C++多线程编程中容器创建线程以及数据共享问题。
#include <vector>
#include <iostream>
#include <thread>
void printTest(int num)
{
std::cout << "子线程:" << num << "启动" << std::endl;
std::cout << "子线程:" << num << "结束" << std::endl;
}
int main()
{
std::vector<std::thread* > test;
for (int i = 0; i < 10; i++)
{
test.push_back(new std::thread(printTest, i));
}
for (auto& pmove : test)
{
pmove->join();
}
std::cout << "主线程" << std::endl;
return 0;
}
1.只读数据:稳定安全,不需要特殊处理,直接读即可
#include <vector>
#include <iostream>
#include <thread>
std::vector<int> g_data={ 1,2,3 };
void printTest(int num)
{
std::cout << "子线程:" << num << "读操作" << std::endl;
for (auto pmove : g_data)
{
std::cout << pmove << std::endl;
}
}
int main()
{
std::vector<std::thread* > test;
for (int i = 0; i < 10; i++)
{
test.push_back(new std::thread(printTest, i));
}
for (auto& pmove : test)
{
pmove->join();
}
std::cout << "主线程" << std::endl;
return 0;
}
2.有读有写:需要做特别处理(写只做写,读只做读操作,保持共享数据只有唯一操作),不然会引发奔溃
#include <list>
#include <iostream>
#include <thread>
class SeaKing
{
public:
void makeFriend()
{
for (int i = 0; i < 100000; i++)
{
std::cout << "增加一个" << std::endl;
mm.push_back(i);
}
}
void breakUp()
{
for (int i = 0; i < 100000; i++)
{
if (!mm.empty())
{
std::cout << "减少一个:"<<mm.front() << std::endl;
mm.pop_front();
}
else
{
std::cout << "已空" << std::endl;
}
}
}
protected:
std::list<int> mm;
};
int main()
{
SeaKing man;
std::thread t1(&SeaKing::makeFriend, &man);
std::thread t2(&SeaKing::breakUp, &man);
t1.join();
t2.join();
return 0;
}
//以上程序会异常退
1.互斥量mutex: 互斥量可以理解为锁,他是一个mutex类的对象
通过调用成员函数lock函数进行加锁
通过调用成员函数unlock函数进行解锁
#include <list>
#include <iostream>
#include <thread>
#include <mutex> //1.包含头文件
class SeaKing
{
public:
void makeFriend()
{
for (int i = 0; i < 100000; i++)
{
m_mutex.lock();
std::cout << "增加一个" << std::endl;
mm.push_back(i);
m_mutex.unlock();
}
}
bool readInfo()
{
m_mutex.lock(); //2.加锁
if (!mm.empty())
{
std::cout << "减少一个:" << mm.front() << std::endl;
mm.pop_front();
m_mutex.unlock();
return true;
}
m_mutex.unlock();
return false;
}
void breakUp()
{
for (int i = 0; i < 100000; i++)
{
int result = readInfo();
if (result == false)
{
std::cout << "已空" << std::endl;
}
}
}
protected:
std::list<int> mm;
std::mutex m_mutex; //创建互斥量对象
};
int main()
{
SeaKing man;
std::thread t1(&SeaKing::makeFriend, &man);
std::thread t2(&SeaKing::breakUp, &man);
t1.join();
t2.join();
return 0;
}
注意:lock函数与unlock都是成对出现,如果lock了没有调用unlock会引发异常,abort终止程序
2.通过lock_guard加锁。
#include <list>
#include <iostream>
#include <thread>
#include <mutex>
class SeaKing
{
public:
void makeFriend()
{
std::lock_guard<std::mutex> sbguard(m_mutex);
for (int i = 0; i < 100000; i++)
{
std::cout << "增加一个" << std::endl;
mm.push_back(i);
}
}
bool readInfo()
{
std::lock_guard<std::mutex> sbguard(m_mutex);
if (!mm.empty())
{
std::cout << "减少一个:" << mm.front() << std::endl;
mm.pop_front();
return true;
}
return false;
}
void breakUp()
{
for (int i = 0; i < 100000; i++)
{
int result = readInfo();
if (result == false)
{
std::cout << "已空" << std::endl;
}
}
}
protected:
std::list<int> mm;
std::mutex m_mutex;
};
int main()
{
SeaKing man;
std::thread t1(&SeaKing::makeFriend, &man);
std::thread t2(&SeaKing::breakUp, &man);
t1.join();
t2.join();
return 0;
}
其实lock_guard 在构造函数中进行lock,在析构函数中进行unlock,本质上还是lock与unlock操作。
好了,创建线程就介绍到这里,大家可以先练习一下,下章节讲解共享数据访问。喜欢的不如点个“在看”吧
评论
图片
表情
视频
全部评论