免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3965 | 回复: 19

[C++] [结贴]利用std::atomic实现一个lockfree结构,析构的时候崩溃了 [复制链接]

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
发表于 2017-01-03 23:28 |显示全部楼层
本帖最后由 asker160 于 2017-01-04 23:20 编辑

我照着cppreference的例子,为stack增加了一个析构函数:

  #include<atomic>
  template<class T>
  struct node{
      T data;
      node* next;
      node(const T&data):data(data),next(nullptr){}
  };  
  template<class T>
  class stack{
      std::atomic<node<T>*> head;
  public:
      void push(const T&data)
      {   
          node<T>* new_node=new node<T>(data);
          new_node->next=head.load(std::memory_order_relaxed);
          while(!std::atomic_compare_exchange_weak_explicit(
                      &head,
                      &new_node->next,
                      new_node,
                      std::memory_order_release,
                      std::memory_order_relaxed));
      }   
      ~stack(){ //我添加的函数
          node<T>* p=head;
          while(p) {
              node<T>* next=p->next;
              delete p;                                                         
              p=next;
          }
      }
  };  

  int main()
  {
      stack<int> s;
      s.push(1);
      s.push(2);
      s.push(3);
      return 0;
  }
程序执行到~stack,最后一次delete的时候,出错了

  1. $ g++ myatomic.cpp -std=c++11
  2. $ ./a.out
  3. *** Error in `./a.out': munmap_chunk(): invalid pointer: 0x0000000000400b00 ***
  4. ======= Backtrace: =========
  5. /lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7f07173a2725]
  6. /lib/x86_64-linux-gnu/libc.so.6(cfree+0x1a8)[0x7f07173aec18]
  7. ./a.out[0x4008f5]
  8. ./a.out[0x400829]
  9. /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f071734b830]
  10. ./a.out[0x4006d9]
  11. ======= Memory map: ========
  12. 00400000-00401000 r-xp 00000000 08:01 2506641                            /home/x/cpp/x01/a.out
  13. 00601000-00602000 r--p 00001000 08:01 2506641                            /home/x/cpp/x01/a.out
  14. 00602000-00603000 rw-p 00002000 08:01 2506641                            /home/x/cpp/x01/a.out
  15. 022f6000-02328000 rw-p 00000000 00:00 0                                  [heap]
  16. 7f0717022000-7f071712a000 r-xp 00000000 08:01 2102313                    /lib/x86_64-linux-gnu/libm-2.23.so
  17. 7f071712a000-7f0717329000 ---p 00108000 08:01 2102313                    /lib/x86_64-linux-gnu/libm-2.23.so
  18. 7f0717329000-7f071732a000 r--p 00107000 08:01 2102313                    /lib/x86_64-linux-gnu/libm-2.23.so
  19. 7f071732a000-7f071732b000 rw-p 00108000 08:01 2102313                    /lib/x86_64-linux-gnu/libm-2.23.so
  20. 7f071732b000-7f07174eb000 r-xp 00000000 08:01 2102243                    /lib/x86_64-linux-gnu/libc-2.23.so
  21. 7f07174eb000-7f07176ea000 ---p 001c0000 08:01 2102243                    /lib/x86_64-linux-gnu/libc-2.23.so
  22. 7f07176ea000-7f07176ee000 r--p 001bf000 08:01 2102243                    /lib/x86_64-linux-gnu/libc-2.23.so
  23. 7f07176ee000-7f07176f0000 rw-p 001c3000 08:01 2102243                    /lib/x86_64-linux-gnu/libc-2.23.so
  24. 7f07176f0000-7f07176f4000 rw-p 00000000 00:00 0
  25. 7f07176f4000-7f071770a000 r-xp 00000000 08:01 2102281                    /lib/x86_64-linux-gnu/libgcc_s.so.1
  26. 7f071770a000-7f0717909000 ---p 00016000 08:01 2102281                    /lib/x86_64-linux-gnu/libgcc_s.so.1
  27. 7f0717909000-7f071790a000 rw-p 00015000 08:01 2102281                    /lib/x86_64-linux-gnu/libgcc_s.so.1
  28. 7f071790a000-7f0717a7c000 r-xp 00000000 08:01 1312401                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
  29. 7f0717a7c000-7f0717c7c000 ---p 00172000 08:01 1312401                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
  30. 7f0717c7c000-7f0717c86000 r--p 00172000 08:01 1312401                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
  31. 7f0717c86000-7f0717c88000 rw-p 0017c000 08:01 1312401                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
  32. 7f0717c88000-7f0717c8c000 rw-p 00000000 00:00 0
  33. 7f0717c8c000-7f0717cb2000 r-xp 00000000 08:01 2102215                    /lib/x86_64-linux-gnu/ld-2.23.so
  34. 7f0717e8e000-7f0717e93000 rw-p 00000000 00:00 0
  35. 7f0717eae000-7f0717eb1000 rw-p 00000000 00:00 0
  36. 7f0717eb1000-7f0717eb2000 r--p 00025000 08:01 2102215                    /lib/x86_64-linux-gnu/ld-2.23.so
  37. 7f0717eb2000-7f0717eb3000 rw-p 00026000 08:01 2102215                    /lib/x86_64-linux-gnu/ld-2.23.so
  38. 7f0717eb3000-7f0717eb4000 rw-p 00000000 00:00 0
  39. 7ffec8e19000-7ffec8e3a000 rw-p 00000000 00:00 0                          [stack]
  40. 7ffec8edb000-7ffec8edd000 r--p 00000000 00:00 0                          [vvar]
  41. 7ffec8edd000-7ffec8edf000 r-xp 00000000 00:00 0                          [vdso]
  42. ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
复制代码
这个错误到底是怎么回事? 调试的时候是第三次delete的时候崩溃。没有发现程序有什么异常啊。
还请指教!

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2017-01-04 09:09 |显示全部楼层
gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC) 表示正常

论坛徽章:
72
20周年集字徽章-20	
日期:2020-10-28 14:04:30操作系统版块每日发帖之星
日期:2016-07-13 06:20:0015-16赛季CBA联赛之广夏
日期:2016-07-10 09:04:02数据库技术版块每日发帖之星
日期:2016-07-09 06:20:00操作系统版块每日发帖之星
日期:2016-07-09 06:20:00数据库技术版块每日发帖之星
日期:2016-07-07 06:20:00操作系统版块每日发帖之星
日期:2016-07-07 06:20:00操作系统版块每日发帖之星
日期:2016-07-04 06:20:00数据库技术版块每日发帖之星
日期:2016-07-03 06:20:00操作系统版块每日发帖之星
日期:2016-07-03 06:20:00数据库技术版块每日发帖之星
日期:2016-07-02 06:20:00操作系统版块每日发帖之星
日期:2016-07-02 06:20:00
发表于 2017-01-04 14:12 |显示全部楼层
对那块内存加一个watch,看一下在执行哪行代码的时候出的问题

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
发表于 2017-01-04 23:20 |显示全部楼层
加了构造函数stack():head(nullptr){}就解决了。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
发表于 2017-01-05 09:49 |显示全部楼层
你这倒是无锁, 就是有循环。。。。。。。。。。。。。。

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2017-01-05 14:02 |显示全部楼层
zylthinking 发表于 2017-01-05 09:49
你这倒是无锁, 就是有循环。。。。。。。。。。。。。。

楼主的代码来源:http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange

没循环不可能,lock-free不等于wait-free

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
发表于 2017-01-08 16:35 |显示全部楼层
lxyscls 发表于 2017-01-05 14:02
楼主的代码来源:http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange

没循环不可能,l ...

死循环还不如锁,占资源啊!如果用在手机上,耗电,而且别的别干了。

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2017-01-09 09:22 |显示全部楼层
回复 7# yulihua49

加锁的数据结构,多跑四五个线程(每个核跑一个),性能就上不去了,不光上不去,再多还往下掉,不带锁的,还有希望。
死不死循环,还是看数据来源。数据没了,还可以选择用户态pause,要是一直没有,干脆就把调度交出去。



论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
发表于 2017-01-09 18:37 |显示全部楼层
本帖最后由 yulihua49 于 2017-01-09 18:41 编辑
lxyscls 发表于 2017-01-09 09:22
回复 7# yulihua49

加锁的数据结构,多跑四五个线程(每个核跑一个),性能就上不去了,不光上不去,再 ...

消费者得不到数据,死循环等?超过5个线程能比加锁性能高?32核弄32个线程没事死循环等?服务器嗷嗷叫。
如果挂起,还要等事件解挂,跟等锁一样啊!那不就是条件锁吗?

我测试解一次锁大约3~7微秒,是比较慢。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
发表于 2017-01-09 18:46 |显示全部楼层
本帖最后由 yulihua49 于 2017-01-09 18:56 编辑
lxyscls 发表于 2017-01-09 09:22
回复 7# yulihua49

加锁的数据结构,多跑四五个线程(每个核跑一个),性能就上不去了,不光上不去,再 ...

我们这样的:

queue
mutex_lock
cond_lock

消费者:
lock(&mutex_lock);
while(!(p=get(queue))) {  //没有资源
        cond_wait(&cond_lock,&mutex_lock);//消费者在此挂起等待,用户态pause。你会比他效率高?
}
unlock(&mutex_lock);
//p得到资源。
........
生产者:
lock(&mutex_lock);
add(queue,data);
unlock(&mutex_lock)
cond_signal(&cond_lock);//给消费者发信号解锁;
........

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP