【C++ 面试 - 新特性】每日 3 题(八)

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/fYaBd
📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

22. thread 类

语言层面的多线程编程实际上就是对接口进行了一个封装,调用语言提供的接口后,底层还会根据是 Windows 还是 Linux 来调用底层的接口。

#include <iostream>
#include <thread>

using namespace std;

void threadHandle1()
{
    //让子线程睡眠两秒
    std::this_thread::sleep_for(std::chrono::seconds(2)); 
    cout << "hello thread1" << endl;
}

int main()
{
    //创建了一个线程对象 传入了一个线程函数
    std::thread t1(threadHandle1);
    //主线程等待子线程结束,主线程继续往下运行
    //语言级别的主线程结束后不能存在没有运行完的子线程,除非分离子线程
    //t1.join(); 

    //或者 把子线程设置为分离线程,主线程结束,整个进程结束,所有子线程都自动结束了
    t1.detach();   //这个看不到子线程输出信息了

    cout << "main" << endl;

    return 0;
}

再举个例子:

#include <iostream>
#include <thread>

using namespace std;

void threadHandle1(int t)
{
    //让子线程睡眠t秒
    std::this_thread::sleep_for(std::chrono::seconds(t)); 
    cout << "hello thread1" << endl;
}

void threadHandle2(int t)
{
    //让子线程睡眠t秒
    std::this_thread::sleep_for(std::chrono::seconds(t));
    cout << "hello thread2" << endl;
}

int main()
{
    //创建了一个线程对象 传入了一个线程函数
    std::thread t1(threadHandle1, 2);
    std::thread t2(threadHandle2, 3);
    //主线程等待子线程结束,主线程继续往下运行
    t1.join();
    t2.join();
    cout << "main" << endl;

    return 0;
}

23. mutex 互斥锁和 lock_guard

#include <iostream>
#include <thread>
#include <mutex>
#include <list>

using namespace std;

int ticketCount = 100;
std::mutex mtx; //全局的一把互斥锁

void sellTicket(int index)
{
    while (ticketCount > 0) //锁+双重判断
    {
        { //定义一个作用域
            lock_guard<std::mutex>lock(mtx); //出了作用域就自动释放 类似智能指针 
            if (ticketCount > 0) //可能出现最后一个都进来了
            {
                cout << "窗口" << index << "卖出第:" << ticketCount << endl;
                ticketCount--;
            }
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

int main()
{
    list<std::thread>tlist;
    for (int i = 1; i <= 3; i++) {
        tlist.push_back(std::thread(sellTicket, i));
    }
    for (auto& i : tlist)
    {
        i.join();
    }
    cout << "结束" << endl;
    return 0;
}

24. C++的 mutex 源码有看过吗,底层怎么实现的 ?

C++ 的 mutex(互斥锁)底层实现主要依赖于操作系统的线程调度和同步原语。在 Linux 系统中,mutex 的底层实现主要依赖于原子操作(atomic operations)和自旋锁(spinlock)。

原子操作是一种不可中断的操作,它可以确保在多线程环境下对共享数据的访问是原子性的,从而避免了数据竞争。原子操作通常包括原子加载、原子存储和原子操作等。

自旋锁是一种忙等待锁,当一个线程尝试获取已经被其他线程持有的锁时,它会不停地循环检查锁是否已经被释放,直到获取到锁为止。自旋锁适用于锁持有时间较短的场景,因为它可以减少线程切换的开销。

C++ 标准库中的 mutex 类提供了基本的锁功能,如 lock() 和 unlock() 方法。当一个线程调用 lock() 方法时,如果锁没有被其他线程持有,那么该线程会立即获取锁并返回;如果锁已经被其他线程持有,那么该线程会进入睡眠状态,等待锁被释放。当一个线程调用 unlock() 方法时,它会释放持有的锁,唤醒等待该锁的其他线程。

C++11 引入了 std::condition_variable 类,它与 mutex 一起用于实现条件变量。条件变量允许一个或多个线程等待某个条件成立,而另一个线程可以触发这个条件。当条件成立时,等待的线程会被唤醒并继续执行。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值