起因是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. python Queue模块

    先看一个很简单的例子 #coding:utf8 import Queue #queue是队列的意思 q=Queue.Queue(maxsize=10) #创建一个queue对象 for i in ra ...

  2. 高质量C++/C编程指南(林锐)

    推荐-高质量C++/C编程指南(林锐) 版本/状态 作者 参与者 起止日期 备注 V 0.9 草稿文件 林锐   2001-7-1至 2001-7-18 林锐起草 V 1.0 正式文件 林锐   20 ...

  3. .net 制作二维码

    首先  要下载  ThoughtWorks.QRCode.dll 下载地址:http://download.csdn.net/detail/lybwwp/6861821 然后新建项目 把Thought ...

  4. 对​O​p​e​n​C​V​直​方​图​的​数​据​结​构​C​v​H​i​s​t​o​g​r​a​m​的​理​解

    前几天被OpenCV的直方图的数据结构CvHistogram弄得很纠结.上网一搜,也没什么相关的资料.现在有点头绪了,就写点东西,让后面的人好走一些吧. 先来看看CvHistogram的定义: typ ...

  5. Spark Streaming源码解读之State管理之UpdataStateByKey和MapWithState解密

    本期内容 : UpdateStateByKey解密 MapWithState解密 Spark Streaming是实现State状态管理因素: 01. Spark Streaming是按照整个Bach ...

  6. HTTP 2.0的那些事

    转自:http://www.admin10000.com/document/9310.html 在我们所处的互联网世界中,HTTP协议算得上是使用最广泛的网络协议.最近http2.0的诞生使得它再次互 ...

  7. C#学习网站记录

    C# 编程指南--Microfsoft官方C#编程指南 https://msdn.microsoft.com/zh-cn/library/67ef8sbd(v=vs.100).aspx

  8. ApexSQLLog总结

    我们程序最近做更新,要做新功能的测试.程序经常出现大的事务,每次commit之后如果发现数据不对的问题也不能再回滚进行断点调试了,因为数据库数据已经更改了,所以一直想找一个回滚我数据库所有操作的工具. ...

  9. 再议C风格变量声明

    NeoRAGEx2002曾经有一篇文章提到这个问题,但是有很多内容并没有包括,例如const和__declspec. 最近我遇到一些这方面的问题,感觉有必要做一个系统性的总结.后来经过一些实验,得出了 ...

  10. hive中rcfile格式(收藏文)

    首先声明,此文是属于纯粹收藏文,感觉讲的很不错. 本文介绍了Facebook公司数据分析系统中的RCFile存储结构,该结构集行存储和列存储的优点于一身,在MapReduce环境下的大规模数据分析中扮 ...