✍个人博客: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 一起用于实现条件变量。条件变量允许一个或多个线程等待某个条件成立,而另一个线程可以触发这个条件。当条件成立时,等待的线程会被唤醒并继续执行。