尝试用两个线程交替打印1-100的数字,要求一个线程打印奇数,另一个线程打印偶数,并且打印数字从小到大依次递增。
#include <iostream>
using namespace std;
#include <thread>
#include <mutex>
#include <condition_variable>
condition_variable cv;
mutex m_mutex;
void add_j(int num, bool &flag)
{
int i = 1;
while (i <= num)
{
unique_lock<mutex> ul(m_mutex);
cv.wait(ul, [&flag]() { return flag; });
cout << this_thread::get_id() << " : " << i << endl;
flag = false;
i = i + 2;
cv.notify_one();
}
}
void add_o(int num, bool &flag)
{
int i = 2;
while (i <= num)
{
unique_lock<mutex> ul(m_mutex);
cv.wait(ul, [&flag]() { return !flag; });
cout << this_thread::get_id() << " : " << i << endl;
flag = true;
i = i + 2;
cv.notify_one();
}
}
int main()
{
int num = 100;
bool flag = true;
thread t1(add_j, num, ref(flag));
thread t2(add_o, num, ref(flag));
t1.join();
t2.join();
cout << num << endl;
system("pause");
return 0;
}
wait函数:
(1)wait(unique_lock &lck)
当前线程的执行会被阻塞,直到收到 notify 为止。
(2)wait(unique_lock &lck,Predicate pred)
当前线程仅在pred=false时阻塞;如果pred=true时,不阻塞。
wait()可依次拆分为三个操作:释放互斥锁、等待在条件变量上、再次获取互斥锁
notify_one:
notify_one():没有参数、没有返回值。
解除阻塞当前正在等待此条件的线程之一。如果没有线程在等待,则还函数不执行任何操作。如果超过一个,不会指定具体哪一线程。
为什么调用wait系列函数时需要传入一个互斥锁?
因为wait系列函数一般是在临界区中调用的,为了让当前线程调用wait阻塞时其他线程能够获取到锁,因此调用wait系列函数时需要传入一个互斥锁,当线程被阻塞时这个互斥锁会被自动解锁,而当这个线程被唤醒时,又会自动获得这个互斥锁。
因此wait系列函数实际上有两个功能,一个是让线程在条件不满足时进行阻塞等待,另一个是让线程将对应的互斥锁进行解锁。