线程池 | Any、Semaphore类
线程池 | Any、Semaphore类
1.Any类
1 | //Any类 表示可以接受任意数据的类型 |
把Any类的拷贝构造和拷贝赋值都delet是因为私有成员base_是unique_ptr,unique_ptr的拷贝构造和拷贝赋值是delete的。
为什么 Any 类可以承接所有的类型
这个 Any 类可以承接所有类型的原因主要在于它使用了模板和多态的技术。
模板的使用:
1 | template <typename T> |
- 这个构造函数是一个模板函数,这意味着它可以接受任何类型T的数据作为参数。当你使用 Any类创建对象时,例如:
Any a(5);这里T是int,编译器会实例化一个Any<int>的构造函数,它会将5存储在Derive<int>类型的对象中。Any b(std::string("hello"));这里T是std::string,编译器会实例化一个Any<std::string>的构造函数,它会将"hello"存储在Derive<std::string>类型的对象中。
多态的使用:
1 | class Base |
Any类包含一个私有成员base_,它是一个std::unique_ptr<Base>类型的指针,Base是一个基类,并且有一个模板派生类Derive<T>继承自Base。- 在存储数据时,使用
std::make_unique<Derive<T>>(data)创建一个Derive<T>的对象,并将其存储在base_中。由于Derive<T>是从Base派生的,所以可以将Derive<T>的指针存储在std::unique_ptr<Base>中,这利用了多态性。
工作流程解释
假设你创建了一个 Any 对象,如 Any a(5);:
- 调用
Any的模板构造函数,T是int,编译器会生成一个Any<int>的构造函数。 - 这个构造函数会调用
std::make_unique<Derive<int>>(5),创建一个Derive<int>类型的对象,该对象存储了int类型的数据。 - 存储的数据被存储在
Derive<int>的data_成员中。 - 这个
Derive<int>对象的指针被存储在base_中,由于Derive<int>继承自Base,所以可以使用std::unique_ptr<Base>来存储它。
如何存储不同类型的数据
- 当你存储不同类型的数据时,
Any类会为每个类型创建一个对应的Derive<T>派生类实例,通过多态将这些派生类对象存储在base_中。 - 每个
Derive<T>实例都存储了具体类型的数据,并且都可以通过base_指针来管理,因为它们都继承自Base。
提取数据时的类型检查
1 | template<typename T> |
- 当你调用
cast_方法时,使用dynamic_cast<Derive<T>*>(base_.get())尝试将存储的对象转换为Derive<T>*类型。 dynamic_cast会在运行时检查存储的对象是否真的是Derive<T>类型。如果是,它将返回Derive<T>的指针,你可以访问data_成员来获取存储的数据;如果不是,dynamic_cast将返回nullptr,此时会抛出异常,因为存储的对象类型与你想要提取的类型不匹配。
通过这种方式,Any 类利用模板和多态性可以存储和管理不同类型的数据,但在使用 cast_ 方法时,需要确保存储的对象类型和提取时指定的类型一致,否则会引发异常。
总结
- 模板允许
Any类接受任何类型的数据,因为对于不同类型的数据,会生成相应的Derive<T>实例。 - 多态允许将这些不同类型的
Derive<T>实例存储在base_指针中,因为它们都继承自Base。 cast_方法使用dynamic_cast进行运行时类型检查,以确保提取的数据类型与存储的数据类型匹配。
2.Semaphore类
通过条件变量+互斥锁来实现信号量
1 | //实现一个信号量类 |
互斥锁是只有0和1的资源计数器,一个线程拿了以后,资源计数器-1,变为0,那么其他线程不可以拿了就
信号量就是资源数量可以自定义的资源计数器,我们传给limit是多少,那就是多少
wait方法
1 | //获取一个信号量资源 |
获取互斥锁,然后条件变量阻塞等待资源计数器大于0,只有1.被唤醒后,2.拿到锁并且3.满足条件之后才会继续执行。一旦继续执行,那就是代表当前线程满足了条件,就是代表拿到了资源,我们的资源就得要–
post方法
1 | //增加一个信号量资源 |
获取互斥锁,post说明我们用完资源了,资源计数器++。我们不知道自己拿着的资源是不是最后一个,所以只要放回去资源,就要通知其他的线程有资源放回去了,让他们来使用。
想要了解更多信号量的读者:实现线程同步的方法-CSDN博客
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Darlingの妙妙屋!
评论












