创建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<iostream> #include<thread> #include<string> #include<vector> #include<list> 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>构造函数里再对mutex对象进行lock 且std::lock_guard也会自动解锁