转载:一些c++多线程习题 - geloutingyu - 博客园 (cnblogs.com)
知识点:
this_thread::yield(); //当前线程放弃执行,操作系统调度另一线程继续执行
自己手写练习才有感觉:
第一题:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码
方法一:采用this_thread::yield();
#include <thread>
#include <mutex>
using namespace std;
const int countNum = 50;
int flag = 100;
mutex mu;
void fun(int num,string_view str)
{
for (int i=0;i< countNum;++i)
{
while (num != flag)
{
this_thread::yield(); //当前线程放弃执行,操作系统调度另一线程继续执行
}
lock_guard<mutex> lock(mu);
for (int j=0;j<flag;++j)
{
cout << str << ":" << j << endl;
}
flag = (flag == 10 ? 100 : 10);
}
}
int main()
{
thread A(fun, 10, "child");
fun(100, "father");
A.join();
return 0;
}
总结:fun(100, "father");要放在join之间,子线程A先于函数执行前创建了,主要是要让主线程先跑起来,this_thread::yield();使当前线程停止,让另外线程启动。
方法二:采用条件变量condition_variable
#include <mutex>
#include <condition_variable>
using namespace std;
const int countNum = 50;
int flag = 10;
condition_variable cv;
mutex mu;
void fun(int num,string_view str)
{
for (int i=0;i< countNum;++i)
{
unique_lock<mutex> lock(mu);
cv.wait(lock, [&]{return num == flag; });
for (int j=0;j<flag;++j)
{
cout << str << ":" << j << endl;
}
flag = (flag == 10 ? 100 : 10);
cv.notify_one();//唤醒被锁住的线程
}
}
int main()
{
thread A(fun, 10, "child");
fun(100, "father");
A.join();
return 0;
}
总结:condition_variable 只能和unique_lock搭配使用,原因可以看C++11:为什么 std::condition_variable 使用 std::unique_lock? - IT工具网 (coder.work)。
第二题:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推
方法一:采用this_thread::yield();
方法二:采用条件变量condition_variable
总结:注意cv.wait 中填写的条件是 如果为真则执行接下来的代码。