C++11多线程实现的一道面试题

题目:
子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码。

这里涉及到的问题是主线程和子线程之间的切换,也就是说子线程跑一下,然后阻塞,主线程再跑一下,然后在阻塞,如此各循环 50次,注意这里的“各循环”,因为主线程和子线程各自的循环是没有关系的,而是内部各自循环50次。
这里肯定要用到std::mutex和原子操作std::atomic,主要的实现思路就是,原子变量的值符合要求,就开始循环,否则阻塞等着。
主线程代码:

for(int i = 0; i < 50; ++i) //循环50次
{
    lock_guard<mutex> lck(mt);//RAII获取锁
    if(flag % 2 == 1){  //flag的是原子变量(原子变量初值为0,所以子线程先进入循环)
        for(int i = 0; i < 100; ++i)
            cout << "parent thread: " << i << endl;
        flag++;
    }
}

子线程代码:

for(int i = 0; i < 50; ++i){
    lock_guard<mutex> lck(mt);  //RAII获取mutex
    if(flag % 2 == 0){  //子线程运行区域
        for(int i = 0; i < 10; ++i)
            cout << "child thread: " << i << endl;
        flag++;
    }
}

完整代码如下:

#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
using namespace std;
mutex mt;   //互斥量
atomic<int> flag = 0;   //原子变量
void func()
{
    for(int i = 0; i < 50; ++i){
        lock_guard<mutex> lck(mt);  //RAII获取mutex
        if(flag % 2 == 0){  //子线程运行区域
            for(int i = 0; i < 10; ++i)
                cout << "child thread: " << i << endl;
            flag++;
        }
    }
}
int main()
{
    thread t1(func);
    for(int i = 0; i < 50; ++i)
    {
        lock_guard<mutex> lck(mt);
        if(flag % 2 == 1){  //主线程运行区域
            for(int i = 0; i < 100; ++i)
                cout << "parent thread: " << i << endl;
            flag++;
        }
    }

    t1.join();

    return 0;
}

猜你喜欢

转载自blog.csdn.net/u012630961/article/details/80703875