创建10个线程,线程入口函数统一使用myprint,注意事项:
/*子函数*/
void myprint(const int&i) {
cout << "myprint线程开始编号:" << i << endl;
//.....
cout << "myprint线程结束编号:" << i << endl;
}
/*主函数*/
vector<thread>mythread;
for (int i = 0; i < 10; i++) {
mythread.push_back(thread(myprint,i));//匿名对象创建,创建10个线程且同时开始进行
}
for (auto&iter :mythread) {
iter.join();
}
//for (auto iter = mythread.begin(); iter != mythread.end(); iter++) {
// iter->join();
//}
//
注意事项:只读数据是安全稳定的,不需要特别什么处理手段,直接读就可以
/*子函数*/
vector<int>number = {1,2,3};//数据共享
void dataprint(const int&i) {
cout << "dataprint的id:" << this_thread::get_id() << "number数据:"
<< number[0] << number[1] << number[2] << endl;;
}
/*主函数*/
vector<thread>mythread;
for (int i = 0; i < 10; i++) {
mythread.push_back(thread(dataprint, i));
}
for (auto&iter : mythread) {
iter.join();
}
注意事项:
假设:
网络游戏服务器,两个自己创建的线程,一个线程手机玩家命令,另一个线程取出玩家送来的命令
(用成员函数作为线程函数方法写线程)
#include
#include
#include
#include
#include
using namespace std;
class Example {
public:
void messageIn() {
for (int i = 0; i < 10000; i++)
{
cout << "服务器收集数据数量:" << i << endl;
num.push_back(i);
}
}
void messageOut() {
for (int i = 0; i < 10000; i++)
{
if (!num.empty()) {
int comment = num.front();
num.pop_front();
cout << "服务器已发送的数据数量" << i << endl;
}
else {
cout << "messageOut()执行,但目前消息队列中为空" << i << endl;
}
}
cout << "end" << endl;
}
private:
list<int>num;
};
int main() {
Example ex;
thread out(&Example::messageOut,&ex);//第二个参数是 引用,保证线程里用的是同一个对象ex,(防止拷贝新的对象)
thread in(&Example::messageIn,&ex);
out.join();
in.join();
cout << "主线程运行" << endl;
system("pause");
return 0;
}
互斥量是个类对象 理解成一把锁,多个线程尝试用lock()成员函数来枷锁这把锁头,只有一个线程能锁定成功(成功的标志是能返回)。
注意事项:
注意事项:
class Example {
public:
void messageIn() {
for (int i = 0; i < 10000; i++)
{
myMutex.lock();
cout << "服务器收集数据数量:" << i << endl;
num.push_back(i);
myMutex.unlock();
}
}
void messageOut() {
for (int i = 0; i < 10000; i++)
{
if (!num.empty()) {
myMutex.lock();
int comment = num.front();
num.pop_front();
cout << "服务器已发送的数据数量" << i << endl;
myMutex.unlock();
}
else {
cout << "messageOut()执行,但目前消息队列中为空" << i << endl;
}
}
cout << "end" << endl;
}
private:
list<int>num;
mutex myMutex;
};
深入与提升:
为了防止忘记unlock(),引入std::lock_guard的类模板,你忘记unlock,模板会自动unlock
//相当 于智能指针一样(unique_ptr<>):您忘记释放内存,自动给你释放
std::lock_guard类模板:直接取代lock和unlock,用了类模板就不要用lock和unlock
class Example {
public:
void messageIn() {
for (int i = 0; i < 10000; i++)
{
//myMutex.lock();
std::lock_guard<mutex>guard(myMutex);
cout << "服务器收集数据数量:" << i << endl;
num.push_back(i);
// myMutex.unlock();
}
}
void messageOut() {
for (int i = 0; i < 10000; i++)
{
if (!num.empty()) {
//myMutex.lock();
std::lock_guard<mutex>guard(myMutex);
int comment = num.front();
num.pop_front();
cout << "服务器已发送的数据数量" << i << endl;
//myMutex.unlock();
}
else {
cout << "messageOut()执行,但目前消息队列中为空" << i << endl;
}
}
cout << "end" << endl;
}
private:
list<int>num;
mutex myMutex;
};
死锁是至少两个锁头(两个互斥量)才能产生
说明:
class Example {
public:
void messageIn() {
for (int i = 0; i < 10000; i++)
{
myMutex1.lock();
myMutex2.lock();
cout << "服务器收集数据数量:" << i << endl;
num.push_back(i);
myMutex2.unlock();
myMutex1.unlock();
}
}
void messageOut() {
for (int i = 0; i < 10000; i++)
{
if (!num.empty()) {
myMutex2.lock();
myMutex1.lock();
int comment = num.front();
num.pop_front();
cout << "服务器已发送的数据数量" << i << endl;
myMutex2.unlock();
myMutex1.unlock();
}
else {
cout << "messageOut()执行,但目前消息队列中为空" << i << endl;
}
}
cout << "end" << endl;
}
private:
list<int>num;
mutex myMutex1;
mutex myMutex2;
};
class Example {
public:
void messageIn() {
for (int i = 0; i < 10000; i++)
{
myMutex1.lock();
myMutex2.lock();
cout << "服务器收集数据数量:" << i << endl;
num.push_back(i);
myMutex2.unlock();
myMutex1.unlock();
}
}
void messageOut() {
for (int i = 0; i < 10000; i++)
{
if (!num.empty()) {
myMutex1.lock();
myMutex2.lock();
int comment = num.front();
num.pop_front();
cout << "服务器已发送的数据数量" << i << endl;
myMutex2.unlock();
myMutex1.unlock();
}
else {
cout << "messageOut()执行,但目前消息队列中为空" << i << endl;
}
}
cout << "end" << endl;
}
private:
list<int>num;
mutex myMutex1;
mutex myMutex2;
};
2.std::lock()函数模板:可用来处理多个互斥量
class Example {
public:
void messageIn() {
for (int i = 0; i < 10000; i++)
{
cout << "messageIn(),服务器收集数据数量:" << i << endl;
lock(myMutex1, myMutex2);
num.push_back(i);
myMutex2.unlock();
myMutex1.unlock();
}
return;
}
bool outMessage() {
lock(myMutex1, myMutex2);
if (!num.empty()) {
num.pop_front();
myMutex2.unlock();
myMutex1.unlock();
return true;
}
myMutex2.unlock();
myMutex1.unlock();
return false;
}
void messageOut() {
for (int i = 0; i < 10000; i++)
{
bool result = outMessage();
if (result==true) {
cout << "messageOut()执行,服务器已发送的数据数量" << endl;
}
else {
cout << "messageOut()执行,但目前消息队列中为空" << i << endl;
}
}
cout << "end" << endl;
}
private:
list<int>num;
mutex myMutex1;
mutex myMutex2;
};
深入与提升:
std::lock_guard的adopt_lock参数
dopt_lock是个结构体对象,起一个标志作用:表示这个互斥量已经lock
不需要在std::lock_guard构造函数里再对mutex对象进行lock
且std::lock_guard也会自动解锁