2023蚂蚁金服/理想/字节/快手面试笔试题——5个线程交叉打印1~100

发布时间 2023-11-13 20:27:00作者: 宇宙之母蔡依林

原题来自牛客网面经。类似这种多线程轮流打印的手撕题会出现很多次,比如以前就看过类似的3个线程轮流打印ABC。

 

关键点在于:怎么设计机制保证这个顺序,至于要打印的数字,肯定是要用互斥量保护起来。

C++代码如下:

#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <vector>

std::mutex mutex;
std::condition_variable cv;
// 用一个变量来控制该哪个线程打印
int whichToPrint = 0;
int threadCount = 5;

void print(int thread_id) {
    std::unique_lock<std::mutex> lock(mutex);
    int count = 1;
    while (count <= 100) {
        // 如果当前线程还没轮到,就会释放掉lock进入等待状态,等待唤醒
        // 所以这个函数还没结束前,lock是可以被释放给其他线程的
        while (thread_id % threadCount != whichToPrint) {
            cv.wait(lock);
        }
        // 如果获取到lock并且线程id满足条件的话,就会执行下面的代码
        std::cout<<std::this_thread::get_id()<<": "<<count<<std::endl;
        count++;
        whichToPrint++;
        whichToPrint %= threadCount;
        // 已经打印一个数字,通知其他线程
        cv.notify_all();
    }
}

int main() {
    std::vector<std::thread> jobs;
    for (int i = 0; i < threadCount; i++) {
        jobs.emplace_back(print, i);
    }
    for (int i = 0; i < threadCount; i++) {
        jobs[i].join();
    }
    return 0;
}