[c++0x] signal0x

fallening 2011-05-17 03:34:12
仿照 boost::signals 写了一个线程安全的 signal/slot 库,实现了大部分的功能,外加一些新的函数;
代码总共 200 多行,目前只支持 g++4.6/4.7;intel c++12 估计也可以支持,但没有测试过。
代码可以在这里找到;手册在这里,只有使用部分,接下来准备把实现部分写完。

有人有空能帮忙 review 一下么?
同时欢迎 fork.
...全文
221 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
noock 2011-05-24
  • 打赏
  • 举报
回复
但没有定义内部的排列顺序啊,只是说比较运算符是用的小于号而已
fallening 2011-05-23
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 nocky 的回复:]

引用 30 楼 fallening 的回复:

引用 29 楼 nocky 的回复:

引用 15 楼 fallening 的回复:

引用 12 楼 nocky 的回复:
您的优先级是作为map的key排序的,但好像标准里面并没有指定map的内部存储结构(记不清了,手头没有标准文档,请确认一下),这样对于特定的实现可能导致您的优先级排序不正常,优先级失效。

map的定义是:……
[/Quote]
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf

我之前参考的是 n3126,现在标准已经更新到 3242 了;
你可以在 3242 的 776 页最上方找到;



template <class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key, T> > >
class map;
template <class Key, class T, class Compare, class Allocator>
bool operator==(const map<Key,T,Compare,Allocator>& x,
const map<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
bool operator< (const map<Key,T,Compare,Allocator>& x,
const map<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
bool operator!=(const map<Key,T,Compare,Allocator>& x,
const map<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
bool operator> (const map<Key,T,Compare,Allocator>& x,
const map<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
bool operator>=(const map<Key,T,Compare,Allocator>& x,
const map<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
bool operator<=(const map<Key,T,Compare,Allocator>& x,
const map<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
void swap(map<Key,T,Compare,Allocator>& x,
map<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare = less<Key>,
class Allocator = allocator<pair<const Key, T> > >
class multimap;
template <class Key, class T, class Compare, class Allocator>
bool operator==(const multimap<Key,T,Compare,Allocator>& x,
const multimap<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
bool operator< (const multimap<Key,T,Compare,Allocator>& x,
const multimap<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
bool operator!=(const multimap<Key,T,Compare,Allocator>& x,
const multimap<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
bool operator> (const multimap<Key,T,Compare,Allocator>& x,
const multimap<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
bool operator>=(const multimap<Key,T,Compare,Allocator>& x,
const multimap<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
bool operator<=(const multimap<Key,T,Compare,Allocator>& x,
const multimap<Key,T,Compare,Allocator>& y);
template <class Key, class T, class Compare, class Allocator>
void swap(multimap<Key,T,Compare,Allocator>& x,
multimap<Key,T,Compare,Allocator>& y);





noock 2011-05-22
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 fallening 的回复:]

引用 29 楼 nocky 的回复:

引用 15 楼 fallening 的回复:

引用 12 楼 nocky 的回复:
您的优先级是作为map的key排序的,但好像标准里面并没有指定map的内部存储结构(记不清了,手头没有标准文档,请确认一下),这样对于特定的实现可能导致您的优先级排序不正常,优先级失效。

map的定义是:
C/C++ code

template <……
[/Quote]

23.6 container adapters ?
没有找到相关的内容,能不能确切一些,第几页,然后把内容帖出来?
fallening 2011-05-20
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 nocky 的回复:]

我又考虑你那了block与unblock方法基本没什么用,因为它们都还需要一个参数就是指定的函数指针,也就是说我如果想block然后再unblock我仍然需要在其它地方保存那个函数指针,这反而没有直接disconnect然后再connect效率高,因为不需要block/unblock的话,你只需要一个map就可以了,其实block就是disconnect的别名,unblock就是connect的别名。这样占的内在也小了,运行效率也高了。
[/Quote]

我也觉得 block/unblock 没有什么前途,不过 boost::signals 定义了,我也就随大流了~~
至于用 connect/disconnect 替代 block/unblock, 我觉得有点困难,因为 connect 方法在调用的时候是必须要提供参数的,不能直接 connect(connection_type con) 这样调用;之所以会这样,是因为 signal0x 里设计的 connection_type 并不保存具体的 signal 和 slot 信息,为了轻巧起见,只是标示了一个独一无二的 connection。
fallening 2011-05-20
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 nocky 的回复:]

我不是说你不小心,我是说客户代码可能不小心导致行为不一样,而与预期的行为不一致,
比如
<a> doSomethingOnSignal(const signal<void> sig);
<b> doSomethingOnSignal(signal<void> sig);
<c> doSomethingOnSignal(const signal<void>& sig);
<d> doSomethingOnSignal(signal<void>& sig);
这三个的行为非常不一样,特别是<b>会导致原来的消息处理函数丢失,即信号处理函数被执行一次就被清空了。而其它三个函数都没问题。
我建议把
self_type& operator = ( self_type&& other )
去掉,然后使用一个普通的方法替代,比如MoveAssign(self_type& other)
这样客户代码出错的机率会小一些
[/Quote]
容我再想下,C++0x 的 rvalue reference 具体使用我还不是非常理解
fallening 2011-05-20
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 nocky 的回复:]

引用 15 楼 fallening 的回复:

引用 12 楼 nocky 的回复:
您的优先级是作为map的key排序的,但好像标准里面并没有指定map的内部存储结构(记不清了,手头没有标准文档,请确认一下),这样对于特定的实现可能导致您的优先级排序不正常,优先级失效。

map的定义是:
C/C++ code

template < class Key, class T, c……
[/Quote]

在标准文档中可以找到,第23章第6节
http://www.open-std.org/jtc1/sc22/wg21/
noock 2011-05-20
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 fallening 的回复:]

引用 12 楼 nocky 的回复:
您的优先级是作为map的key排序的,但好像标准里面并没有指定map的内部存储结构(记不清了,手头没有标准文档,请确认一下),这样对于特定的实现可能导致您的优先级排序不正常,优先级失效。

map的定义是:
C/C++ code

template < class Key, class T, class Compare = less<Key>,
……
[/Quote]
我仔细看了一下标准文档,文档中没有找到指定map中的value遍历顺序的说明,也就是说,使用迭代器遍历map是并不能确定是按照key的大小排序的,也没说明是从大到小的顺序还是从小到大的顺序排列,所以operator()的行为根据标准是不能确定的,它依赖与一个假设就是map使用抚今迭代器遍历时是按照key的从大到小的顺序进行的,日后如果map的排序算法改变了,或者有些实现顺序是从小到大排列的,那么operator( )执行各信号处理函数的顺序就与优先级不符。
待会儿有空我到各个主流平台上验证一下。
healer_kx 2011-05-19
  • 打赏
  • 举报
回复
不懂啊。。。
noock 2011-05-19
  • 打赏
  • 举报
回复
开始定义的那一堆类型别名,是不是可以重新整理一下,尽可能用private ?

类定义成struct有些不太好,您不是想默认public吗?直接用class会更C++一些

self_type& operator = ( const self_type& other )
self_type& operator = ( self_type&& other )
1)这两个赋值运算符虽然灵活,但太容易出问题,定义变量的时候特别是传参数的时候不小心会导致行为不一致,是不是可以把后者改成一个MoveFrom之类的方法?而且后者用的机会应该不多
2)这两个函数体开始可以加一个判断进行一些优化
if( this == &other) return *this;

您的优先级是作为map的key排序的,但好像标准里面并没有指定map的内部存储结构(记不清了,手头没有标准文档,请确认一下),这样对于特定的实现可能导致您的优先级排序不正常,优先级失效。

3)是不是可以加一个 empty( )方法,难消息横槽是否为空,因为设计的时候可能会设计一些消息,但实际实现的时候可能很多不关心的消息都不需要响应,这样可以提高执行效率,就不再需要执行operator( ),或者在operator( )中先检查一遍队列是否为空。

4)在disconnect的时候,检测一下对应优先级的消息槽列表是否已经为空,如果为空就可以直接在map中去掉这一项,否则可能是一个空列表,会影响执行效率。因为disconnect执行次数一般来讲很少的,而operator( )执行频率很高,在disconnect里做一些优化工作是值得的。

qq120848369 2011-05-19
  • 打赏
  • 举报
回复
新新人类..
  • 打赏
  • 举报
回复
冻结 2011-05-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dizuo 的回复:]

lz玩的太高端了啊,偶落伍咧。。。
[/Quote]
同落。。。
無_1024 2011-05-19
  • 打赏
  • 举报
回复
看不懂
fallening 2011-05-19
  • 打赏
  • 举报
回复
唉,自己 up
noock 2011-05-19
  • 打赏
  • 举报
回复
我又考虑你那了block与unblock方法基本没什么用,因为它们都还需要一个参数就是指定的函数指针,也就是说我如果想block然后再unblock我仍然需要在其它地方保存那个函数指针,这反而没有直接disconnect然后再connect效率高,因为不需要block/unblock的话,你只需要一个map就可以了,其实block就是disconnect的别名,unblock就是connect的别名。这样占的内在也小了,运行效率也高了。
noock 2011-05-19
  • 打赏
  • 举报
回复
类型定义时还是换用class吧,多写一行public也没什么,默认public与private这种细节很多人不一定知道的,显示使用private可读性会好一些,既然原代码都拿出来共享了,为什么不共享得更清楚,更彻底一些呢?
noock 2011-05-19
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 fallening 的回复:]

1) 这两个 operator= 行为是不一致的,一个是 copy assignment; 另一个是 move assignment
2) 这个问题 exceptional C++ 有专门的一节讨论(#38)
[/Quote]

我不是说你不小心,我是说客户代码可能不小心导致行为不一样,而与预期的行为不一致,
比如
<a> doSomethingOnSignal(const signal<void> sig);
<b> doSomethingOnSignal(signal<void> sig);
<c> doSomethingOnSignal(const signal<void>& sig);
<d> doSomethingOnSignal(signal<void>& sig);
这三个的行为非常不一样,特别是<b>会导致原来的消息处理函数丢失,即信号处理函数被执行一次就被清空了。而其它三个函数都没问题。
我建议把
self_type& operator = ( self_type&& other )
去掉,然后使用一个普通的方法替代,比如MoveAssign(self_type& other)
这样客户代码出错的机率会小一些
fallening 2011-05-19
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 fallening 的回复:]

引用 21 楼 healer_kx 的回复:

哦...


方才 google 了一下,大致知道了 win32 的 event 是做什么的;
在 c++0x 中,可以使用 condition variable 和 future 实现这种多线程同步功能。
[/Quote]

如果感兴趣,可以先去看看 C++0x 的草稿,然后再翻翻 C++ Concurrency in Action 这本书。
fallening 2011-05-19
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 healer_kx 的回复:]

哦...
[/Quote]

方才 google 了一下,大致知道了 win32 的 event 是做什么的;
在 c++0x 中,可以使用 condition variable 和 future 实现这种多线程同步功能。
healer_kx 2011-05-19
  • 打赏
  • 举报
回复
哦...
加载更多回复(12)

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧