3-30

类型转换

const_cast<>

去掉(指针或引用)常量属性,里面必须时指针或引用类型,但通过指针也无法更改常量的值
alt text

static_cast<>

提供编译器认为安全的类型转换
转换有效:alt text
转换无效:alt text

reinterpret_cast<>

类似c风格的强制类型转换, 不安全
alt text转换有效

dynamic_cast<>

用于继承结构中,可以支持RTTI类型识别的上下转换
alt text
alt text

C++多线程编程

相关库:

#include <thread>
#include <mutex> //互斥锁
#include <condition_variable>

相关函数实现

线程:

创建线程: thread t(func, a, b, ...); // 创建一个线程对象, func为线程函数, a, b...为函数参数
t.join() //主线程要等待子线程t运行结束
若主线程运行结束后,还留有未运行完成的子线程会报错
可以用: t.detch() //把子线程t设置为和主线程分离的线程, 这样就不会报错
std::this_thread命名空间, 里面封装了许多函数
如:get_id() //获取线程id
    sleep() // 睡眠
    sleep_for() //睡多长时间
    sleep_until() //睡到什么时候
std::chrono命名空间, 封装了一些时间相关的函数

锁:

std::mutex mtx;//定义一把锁
mtx.lock() , mtx.unlock() //加锁解锁
但由于加锁后若直接return了可能unlock调用不到无法解锁, 造成死锁

解决:
std::mutex mtx;
std::lock_guard<std::mutex> lck(mtx);
使用lock_guard封装了一把锁,出了{}(作用域)后会自动析构,无需担心死锁问题,也不用手动加锁解锁,禁止了拷贝构造和拷贝复制,**所以不能用于函数参数或者返回值**

std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
使用unique_lock封装了一把锁,出了{}(作用域)后会自动析构,无需担心死锁问题,也不用手动加锁解锁
禁止了拷贝构造和拷贝复制,**可以使用移动构造和移动复制**,类似于unique_ptr
二者都运用了智能指针的思想

线程通信:

条件变量:condition_variable

常与一把互斥锁一起使用
定义: condition_variable cv;
cv.wait(lck); // lck 只能是unique_lock<std::mutex>类型
作用:首先线程的状态变为等待状态, 第二步释放所拿到的锁
cv.notify_all() / cv.notify_one()
作用:唤醒其他的所有/一个线程,被唤醒的线程由等待变为*阻塞*状态,只有拿到锁后才变成就绪态

信号量:

表示资源数量?
P操作:资源数+1
V操作:资源数-1
二元信号量时作用跟互斥锁是类似的,但信号量所有线程都可以操作,但互斥锁只能由持有它的线程释放这把锁