本文共 2963 字,大约阅读时间需要 9 分钟。
创建多个线程是一个常见的操作,但如果不正确管理,可能会导致逻辑错误或性能问题。在C++中,可以通过std::thread
来创建线程,并使用join
方法等待所有线程结束。
【引例】
#include#include #include using namespace std;void myprint(int val) { cout << "myprint线程开始执行了,编号为: " << val << endl; // ... cout << "myprint线程执行完毕了,编号为: " << val << endl; return; }int main() { vector my_threads; for (int i = 0; i < 10; ++i) { my_threads.push_back(thread(myprint, i)); } for (auto iter = my_threads.begin(); iter != my_threads.end(); ++iter) { iter->join(); } cout << "主线程结束" << endl; return 0; }
要点:
join
方法等待所有子线程结束,避免主线程等待时间过长。在多线程环境中,数据共享可能导致竞态条件或其他并发问题。以下是常见情况的分析:
只读数据是安全的,因为所有线程都只能读取,不会修改数据。直接使用即可。
【示例】
#include#include #include using namespace std;vector vec{1, 2, 3}; void myprint(int val) { cout << "线程id为:" << this_thread::get_id() << "\tvec的值\t" << vec[0] << "\t" << vec[1] << "\t" << vec[2] << endl; }int main() { vector my_threads; for (int i = 0; i < 10; ++i) { my_threads.push_back(thread(myprint, i)); } for (auto iter = my_threads.begin(); iter != my_threads.end(); ++iter) { iter->join(); } cout << "主线程结束" << endl; return 0; }
要点:
当有线程同时进行读和写操作时,必须采取措施防止竞态条件。最简单的方法是确保读操作和写操作互斥。
【示例】
假设有2个写线程和8个读线程,直接操作共享数据会导致崩溃。正确的做法是:// 示例不提供完整代码,但核心思想是: // - 在写操作时,阻止其他线程读取 // - 在读操作时,确保数据已写好
要点:
mutex
)是解决这种情况的常用方法。场景: 网络游戏服务器,两个线程分别处理玩家命令。
#include#include #include #include
using namespace std;class A { public: void inMsgRecvQueue() { for (int i = 1; i < 10000; ++i) { cout << "inMsgRecvQueue执行了,插入一个元素 " << i << endl; msgRecvQueue.push_back(i); } } void outMsgRecvQueue() { for (int i = 1; i < 10000; ++i) { if (!msgRecvQueue.empty()) { int command = msgRecvQueue.front(); msgRecvQueue.pop_front(); // 根据command执行具体操作 } else { cout << "outMsgRecvQueue执行了,但是当前消息队列为空 " << i << endl; } } cout << "outMsgRecvQueue()执行完毕" << endl; } private: list msgRecvQueue; }; int main() { A obja; thread outMsgThread(&A::outMsgRecvQueue, &obja); thread inMsgThread(&A::inMsgRecvQueue, &obja); inMsgThread.join(); outMsgThread.join(); cout << "主线程结束" << endl; return 0; }
问题:
解决方法:
通过以上内容,可以看出多线程开发中数据共享问题的关键在于正确管理共享资源,避免竞态条件,并在需要时使用互斥机制确保线程安全。
转载地址:http://mbyr.baihongyu.com/