起因是event_base 跨线程add/remove event 导致崩溃或者死循环。

据查:libvent 1.4.x是非线程安全的,要跨线程执行event_add,会有问题。
因此传统做法是通过pipe来通知宿主线程执行event_add操作。
libevent 2.0.x通过线程锁做到了线程安全,可以跨线程执行event_add。

需要在创建event_base之前调用evthread_use_pthreads(),需要添加event_pthread 库,函数定义在event/thread.h

// 原理参照自 http://blog.chinaunix.net/uid-17260303-id-3342299.html

libevent关于多线程的使用需要在所有的初始化之前加evthread_use_pthreads()函数的原因:
evthread_use_pthreads()定义在evthread_pthread.c里面。在这个函数里,初始化了一个evthread_lock_callbacks对象 cbs,然后调用evthread_set_lock_callbacks(&cbs);来的对cbs这个evthread_lock_callbacks对象做操作。evthread_set_lock_callbacks定义在evthread.c里面。在这个函数里,其实就是将cbs的值赋值给了全局变量_evthread_lock_fns。
在定义了_EVENT_DISABLE_THREAD_SUPPORT的情况下
在add_event函数里面,libevent调用了EVBASE_ACQUIRE_LOCK这个宏。这个宏定义在evthread-internal.h, 同时EVBASE_ACQUIRE_LOCK这个宏又调用了EVLOCK_LOCK,EVLOCK_LOCK又调用了全局变量_evthread_lock_fns的lock成员。这个_evthread_lock_fns就是之前说过的那个。所以其实就是调用了evthread_use_pthreads()函数设置的_evthread_lock_fns这个结构体的lock成员。而这个lock成员函数,根据evthread_use_pthreads()函数里面设置的值,就是evthread_posix_lock函数,其中参数mode是0,参数_lock是base.th_base_lock。所以其实就是pthread_mutex_lock(base.th_base_lock)
在没有定义_EVENT_DISABLE_THREAD_SUPPORT的情况下
在add_event函数里面,libevent调用了EVBASE_ACQUIRE_LOCK这个宏。这个宏定义在evthread-internal.h, 同时EVBASE_ACQUIRE_LOCK这个宏又调用了EVLOCK_LOCK,EVLOCK_LOCK又调用了函数_evthreadimpl_lock_lock(),参数mode是0,参数lock是base.th_base_lock。_evthreadimpl_lock_lock定义在evthread.c里面。在_evthreadimpl_lock_lock函数里面,会先判断全局变量_evthread_lock_fns的lock存不存在。如果存在就调用_evthread_lock_fns的lock成员,相当于就是调用evthread_posix_lock函数了,就和定义了_EVENT_DISABLE_THREAD_SUPPORT的情况一样了。如果不存在就什么都不干,返回0。
因为我的环境里面是没有定义_EVENT_DISABLE_THREAD_SUPPORT的,所以如果不在开始的时候调用evthread_use_pthreads(),那么全局变量_evthread_lock_fns就没有被赋值,他的lock成员自然也就是NULL了。所以,EVBASE_ACQUIRE_LOCK宏其实什么都没干,也就没有加锁,所以在多个线程里面add_event会乱掉()
 

Libevent 的多线程操作的更多相关文章

  1. 使用libevent进行多线程socket编程demo

    最近要对一个用libevent写的C/C++项目进行修改,要改成多线程的,故做了一些学习和研究. libevent是一个用C语言写的开源的一个库.它对socket编程里的epoll/select等功能 ...

  2. C#中级-常用多线程操作(持续更新)

    一.前言       多线程操作一直是编程的常用操作,掌握好基本的操作可以让程序运行的更加有效.本文不求大而全,只是将我自己工作中常常用到的多线程操作做个分类和总结.平时记性不好的时候还能看看.本文参 ...

  3. java多线程操作

    进程是程序的一次动态的执行过程,它经历了从代码加载.执行完毕的一个完整过程,这个过程也是进程本身从产生.发展到最终消亡的过程. 多线程是实现并发机制的一种有效的手段.进程和线程一样,都是实现并发的一个 ...

  4. MFC的多线程操作

    记得用MFC做了一个图像自动修复软件,当时没有多线程操作这一概念,由于图像修复算法比较复杂,因此,当执行图像修复时,程序就像卡死了似得而不能做其他操作.其实MFC对这种情况有一种很好地解决方案,那就是 ...

  5. 更高效地提高redis client多线程操作的并发吞吐设计

    Redis是一个非常高效的基于内存的NOSQL数据库,它提供非常高效的数据读写效能.在实际应用中往往是带宽和CLIENT库读写损耗过高导致无法更好地发挥出Redis更出色的能力.下面结合一些redis ...

  6. C#多线程操作界面控件的解决方案(转)

    C#中利用委托实现多线程跨线程操作 - 张小鱼 2010-10-22 08:38 在使用VS2005的时候,如果你从非创建这个控件的线程中访问这个控件或者操作这个控件的话就会抛出这个异常.这是微软为了 ...

  7. c# BackGroundWorker 多线程操作的小例子

    在我们的程序中,经常会有一些耗时较长的运算,为了保证用户体验,不引起界面不响应,我们一般会采用多线程操作,让耗时操作在后台完成,完成后再进行处理或给出提示,在运行中,也会时时去刷新界面上的进度条等显示 ...

  8. swift语言之多线程操作和操作队列(下)———坚持51天吃掉大象(写技术文章)

    欢迎有兴趣的朋友,参与我的美女同事发起的活动<51天吃掉大象>,该美女真的很疯狂,希望和大家一起坚持51天做一件事情,我加入这个队伍,希望坚持51天每天写一篇技术文章.关注她的微信公众号: ...

  9. C# winform编程中多线程操作控件方法

    private void Form1_Load(object sender, EventArgs e) { Thread newthread = new Thread(new ThreadStart( ...

随机推荐

  1. PMIC RTC 寄存器

    RTC_PDN1 bit 0 - 3 : Android bits bit 4 - 5 : Recovery bits (0x10: factory data reset) bit 6 : Bypas ...

  2. mklink

    $ mklink /D 参数:创建目录类型链接

  3. MyEclipse10建立Maven Webapp项目并通过git传到GitHub

    先创建Maven Webapp项目 图文详解MyEclipse中新建Maven webapp项目的步骤(很详细) 在web项目的路径中右键(前提是你机器已经装了git)“Git Init Here”, ...

  4. AUTOIT解决域控普通用户以管理员身份安装软件方法

    windows域管理,本是很好的管理方式,方便的软件分发,权限控制等功能.不过由于我处软件分发总有那么一些电脑没有成功安装,或是新装的电脑安装软件时漏了安装一些软件,而这些软件需要管理员权限安装的,用 ...

  5. 关于android 5.0对开发带来的影响

    由于google推出了android5.0的系统,在app的安装方式,权限的管理方面与之前的系统有较大的区别.自己做的app也有体会.现在记录一些要注意的东西,防止忘记: 1.5.0改变了对自定义权限 ...

  6. java.lang.IllegalArgumentException: template not initialized; call afterPropertiesSet() before using

    在使用spring-data-redis时使用junit测试报错: java.lang.IllegalArgumentException: template not initialized; call ...

  7. JS中Array详细用法

    1.数组的创建 var name= new Array(); //创建一个数组 name[0]="zhangsan";   //给数组赋值 name[1]="lisi&q ...

  8. [转] ACM中国国家集训队论文集目录(1999-2009)

    国家集训队1999论文集 陈宏:<数据结构的选择与算法效率——从IOI98试题PICTURE谈起>来煜坤:<把握本质,灵活运用——动态规划的深入探讨>齐鑫:<搜索方法中的 ...

  9. ArcGIS api fo silverlight学习一(silverlight加载GeoServer发布的WMS地图)

    最好的学习资料ArcGIS api fo silverlight官网:http://help.arcgis.com/en/webapi/silverlight/samples/start.htm 一. ...

  10. <读书笔记>软件调试之道 :问题的核心-修复后的反思

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...