在C++中使用信号和槽(sigslot库介绍,含demo链接)

本文介绍了C++中的sigslot库,它提供了一种类型安全、线程安全的信号和槽机制。文章详细阐述了sigslot库的使用场景、参数类型、信号连接与断开、信号触发以及线程安全特性,并通过一个示例展示了如何在C++中使用sigslot库来实现信号与槽的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,使用场景

     在编码过程中,我们经常会碰到一种场景:当某个业务触发的时候,需要通知到不同的模块,让各个模块对这些触发的业务进行不同的处理。这也就是设计模式中常见的生产者与观察者模式。在QT中,对于观察者模式有现成的封装好的信号与槽,可以很方便地使用,但是当进行代码移植或者在非QT环境上开发时,开发环境是没有提供现有的信号机制的,我们常常需要自己来实现,而在这种情况下,sigslot库是一个比较好的选择。

二,sigslot库简介

     sigslot库, 它是用C++实现的具有类型安全,线程安全的信号和槽机制的库。它完全使用C++语言编写,只有一个头文件,因此避免了在使用的时候进行源码的预编译。sigslot的主页是http://sigslot.sourceforge.net。

1,参数类型

     Signal和Slots也是可以带一个或多个指定类型的参数。库sigslot是建立在C++的templated机制上的,所以在signal和solts的声明和调用的时候都会进行完全的类型检查。
     signal类型的命名规则是signaln<type1, type2> n是参数的个数。signal最多支持8个参数。
在这里插入图片描述

2,信号连接与槽

     信号的连接是使用方法类signaln<>的成员方法connect().方法connect()需要指定两个参数:
在这里插入图片描述
(1) 指向目标实例的指针
(2) 指向目标实例的成员方法的指针

     为了让方法connect()能够工作,需要目标实例的类继承于has_slots.
     一个信号是可以连接到任意数量的槽上的,当信号被发送的时候,所有连接到这个信号上的槽都会被调用。槽的调用对信号是无感的,所以槽方法的返回值都是void类型。
     在现在的实现中槽方法是使用std::list进行存储的:
在这里插入图片描述
     这也就意味着当一个信号连接了多个槽的时候,槽方法的调用顺序和其被连接的顺序是一致的。(在未来的版本中可能会对这个行为进行修改,因此我们不能确保槽方法的调用顺序一定会和其被连接的顺序一致。改进方法很简单,可以加优先级,将存储信号的容器换为优先队列,根据自己的业务需求进行拓展)

3,信号与槽的断开

     当信号实体或者槽实体被析构的时候,信号与槽的连接也就被断开了。但是在需要的时候我们还是可以调用signal的成员方法disconnec(&)来断开连接。
在这里插入图片描述
     signal的disconnect()会断开当前信号与当前槽的连接单个连接,signal的disconnect_all()会断开当前信号与所有槽的连接,has_slotsdisconnec_all()可以用来断开与该槽连接的所有信号。

4,信号的触发

     当信号发射时,通常称为信号触发,假设一个信号定义为:

signal2<char *, int> ReportError;

     我们使用如下两种方法来发送这个信号:

ReportError("Something went wrong", ERR_SOMETHING_WRONG);
ReportError.emit("Something went wrong", ERR_SOMETHING_WRONG);

     方法1是signal基类重载了函数操作运算符(),内部其实还是调用了emit函数。

5,信号的线程安全

sigslot库目前支持三种可选的信号线程策略:
(1)Single Threaded
     在单线程模式下,库不会尝试跨线程保护其内部数据结构。因此,对构造函数、析构函数和信号的所有调用必须存在于单个线程中。
(2)Multithreaded Global
     在多线程全局模式下,库使用单个全局关键部分保护其内部数据结构。这种方法在锁使用方面几乎没有开销或内存,但是锁的粒度比较大,有时可能会阻塞,因为所有信号共用一把锁。
(3)Multithreaded Local
     在多线程本地模式下,库为每个对象使用单独的锁。这意味着每个信号都有自己的锁,当信号较多时,导致锁的创建开销加大,但是这种策略锁的粒度小,各个锁之间互不干扰。

6,槽的线程安全

     sigslot库不能自动保证槽是线程安全的,但是它也提供了两个可用的锁。has slots类继承多线程策略,依次提供成员函数lock()和unlock(),用于保护内部数据结构用于实现信号/插槽机制。比如:

class MyMultithreadedClass
: 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Simple Simple

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值