这篇“C++怎么实现两个线程交替打印”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++怎么实现两个线程交替打印”文章吧。
首先简单搭一个框架,让两个线程先尝试实现交替打印。
//实现两个线程交替打印 #include <iostream> #include <thread> using namespace std; int main(void) { int n = 100; int i = 0; //创建两个线程 thread t1([&n, &i](){ while (i < n) { cout << i << " "; i++; } }); thread t2([&n, &i]() { while (i < n) { cout << i << " "; i++; } }); if (t1.joinable()) { t1.join(); } if (t2.joinable()) { t2.join(); } return 0; }
为了让我们更加清楚是哪个线程打印了,我们需要获取线程的ID。
#include <iostream> #include <thread> using namespace std; int main(void) { int n = 100; int i = 0; //创建两个线程 thread t1([&n, &i](){ while (i < n) { cout << this_thread::get_id() << ": " << i << endl; i++; } }); thread t2([&n, &i]() { while (i < n) { cout << this_thread::get_id() << ": " << i << endl; i++; } }); if (t1.joinable()) { t1.join(); } if (t2.joinable()) { t2.join(); } return 0; }
这显然没有完成两个线程交替打印的目的,甚至数据的打印都非常地乱。这是因为i是临界资源,多个线程争抢访问临界资源可能会造成数据二义,线程是不安全的,需要保证任意时刻只有一个线程能够访问临界资源。
所以创建一个互斥量,并在临界区合适的地方加锁和解锁。由于线程的执行函数我使用了lambda表达式,为了让两个线程使用的是同一把锁,把锁创建在了main函数内,并在lambda表达式内使用了引用捕捉。
#include <iostream> #include <thread> #include <mutex> using namespace std; int main(void) { int n = 100; int i = 0; mutex mtx; //创建两个线程 thread t1([&n, &i, &mtx](){ while (i < n) { mtx.lock(); cout << this_thread::get_id() << ": " << i << endl; i++; mtx.unlock(); } }); thread t2([&n, &i, &mtx]() { while (i < n) { mtx.lock(); cout << this_thread::get_id() << ": " << i << endl; i++; mtx.unlock(); } }); if (t1.joinable()) { t1.join(); } if (t2.joinable()) { t2.join(); } return 0; }
在C++中,一般不直接操作锁,而是由类去管理锁。
//第一个管理锁的类 template <class Mutex> class lock_guard; //第二个管理锁的类 template <class Mutex> class unique_lock;
lock_guar类,只有构造和析构函数。一般用于加锁和解锁,这里进行简单的模拟:
//注意:为了使得加锁和解锁的是同一把锁 //需要使用引用 template <class Lock> class LockGuard { public: LockGuard(Lock &lck) :_lock(lck) { _lock.lock(); } ~LockGuard() { _lock.unlock(); } private: Lock &_lock; };
unique_lock的成员方法就不仅仅是析构函数和构造函数。详见文档unique_lock介绍和使用。
这里将锁交给unique_lock类的对象进行管理。
int main(void) { int n = 100; int i = 0; mutex mtx; //创建两个线程 thread t1([&n, &i, &mtx, &cv, &flag](){ while (i < n) { unique_lock<mutex> LockManage(mtx); cout << this_thread::get_id() << ": " << i << endl; i++; } }); thread t2([&n, &i, &mtx, &cv, &flag]() { while (i < n) { unique_lock<mutex> LockManage(mtx); cout << this_thread::get_id() << ": " << i << endl; i++; } }); if (t1.joinable()) { t1.join(); } if (t2.joinable()) { t2.join(); } return 0; }C++怎么实现两个线程交替打印