qemu2事件处理机制 这篇文章虽然分析了事件机制,但是对线程模型,和锁的模型还是云里雾里,为什么这么说呢,因为当时分析的qemu版本对aio这里的管理也是相当混乱,比方说aio_set_fd_handler这个函数,明明只能在aio 线程调用,却又执行notify aio线程,这本身是自相矛盾的,让分析者百思不得其解。

不过在新版本的qemu有了很大改善,我们可以再来看下aio 的api

QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
{QEMUBH *bh;bh = g_new(QEMUBH, 1);*bh = (QEMUBH){.ctx = ctx,.cb = cb,.opaque = opaque,};qemu_lockcnt_lock(&ctx->list_lock);bh->next = ctx->first_bh;/* Make sure that the members are ready before putting bh into list */smp_wmb();ctx->first_bh = bh;qemu_lockcnt_unlock(&ctx->list_lock);return bh;
}

这段代码已经使用ctx->list_lock进行保护了

void aio_set_fd_handler(AioContext *ctx,int fd,bool is_external,IOHandler *io_read,IOHandler *io_write,AioPollFn *io_poll,void *opaque)
{AioHandler *node;bool is_new = false;bool deleted = false;int poll_disable_change;qemu_lockcnt_lock(&ctx->list_lock);node = find_aio_handler(ctx, fd);/* Are we deleting the fd handler? */if (!io_read && !io_write && !io_poll) {if (node == NULL) {qemu_lockcnt_unlock(&ctx->list_lock);return;}/* If the GSource is in the process of being destroyed then* g_source_remove_poll() causes an assertion failure.  Skip* removal in that case, because glib cleans up its state during* destruction anyway.*/if (!g_source_is_destroyed(&ctx->source)) {g_source_remove_poll(&ctx->source, &node->pfd);}/* If a read is in progress, just mark the node as deleted */if (qemu_lockcnt_count(&ctx->list_lock)) {node->deleted = 1;node->pfd.revents = 0;} else {/* Otherwise, delete it for real.  We can't just mark it as* deleted because deleted nodes are only cleaned up while* no one is walking the handlers list.*/QLIST_REMOVE(node, node);deleted = true;}poll_disable_change = -!node->io_poll;} else {poll_disable_change = !io_poll - (node && !node->io_poll);if (node == NULL) {/* Alloc and insert if it's not already there */node = g_new0(AioHandler, 1);node->pfd.fd = fd;QLIST_INSERT_HEAD_RCU(&ctx->aio_handlers, node, node);g_source_add_poll(&ctx->source, &node->pfd);is_new = true;}/* Update handler with latest information */node->io_read = io_read;node->io_write = io_write;node->io_poll = io_poll;node->opaque = opaque;node->is_external = is_external;node->pfd.events = (io_read ? G_IO_IN | G_IO_HUP | G_IO_ERR : 0);node->pfd.events |= (io_write ? G_IO_OUT | G_IO_ERR : 0);}/* No need to order poll_disable_cnt writes against other updates;* the counter is only used to avoid wasting time and latency on* iterated polling when the system call will be ultimately necessary.* Changing handlers is a rare event, and a little wasted polling until* the aio_notify below is not an issue.*/atomic_set(&ctx->poll_disable_cnt,atomic_read(&ctx->poll_disable_cnt) + poll_disable_change);aio_epoll_update(ctx, node, is_new);qemu_lockcnt_unlock(&ctx->list_lock);aio_notify(ctx);if (deleted) {g_free(node);}
}

同样aio_set_fd_handler 也使用ctx->list_lock进行了保护。

另外timer还是只能在aio thread中调用。

BlockAIOCB *thread_pool_submit_aio(ThreadPool *pool,ThreadPoolFunc *func, void *arg,BlockCompletionFunc *cb, void *opaque)
{ThreadPoolElement *req;req = qemu_aio_get(&thread_pool_aiocb_info, NULL, cb, opaque);req->func = func;req->arg = arg;req->state = THREAD_QUEUED;req->pool = pool;QLIST_INSERT_HEAD(&pool->head, req, all);trace_thread_pool_submit(pool, req, arg);qemu_mutex_lock(&pool->lock);if (pool->idle_threads == 0 && pool->cur_threads < pool->max_threads) {spawn_thread(pool);}QTAILQ_INSERT_TAIL(&pool->request_list, req, reqs);qemu_mutex_unlock(&pool->lock);qemu_sem_post(&pool->sem);return &req->common;
}

thread_pool_submit_aio没有锁保护,只能在aio thread调用,注意pool->lock只能保护ThreadPool状态,并不能保护pool->head。

所以在新版的qemu中。线程状态混乱的问题应该得到了很多改善。另外文件描述符事件的设置也可以放到非aio 线程执行了。

qemu AIO线程模型相关推荐

  1. Netty和RPC框架线程模型分析

    <Netty 进阶之路>.<分布式服务框架原理与实践>作者李林锋深入剖析Netty和RPC框架线程模型.李林锋已在 InfoQ 上开设 Netty 专题持续出稿,感兴趣的同学可 ...

  2. Netty 和 RPC 框架线程模型分析

    https://www.infoq.cn/article/9Ib3hbKSgQaALj02-90y 1. 背景 1.1 线程模型的重要性 对于 RPC 框架而言,影响其性能指标的主要有三个要素: I/ ...

  3. c++ 多个线程操作socket要同步吗_基础知识深化:NIO优化原理和Tomcat线程模型

    1.I/O阻塞 书上说BIO.NIO等都属于I/O模型,但是I/O模型这个范围有点含糊,我为此走了不少弯路.我们日常开发过程中涉及到NIO模型应用,如Tomcat.Netty中等线程模型,可以直接将其 ...

  4. netty应用场景_彻底搞懂 netty 线程模型

    编者注:Netty是Java领域有名的开源网络库,特点是高性能和高扩展性,因此很多流行的框架都是基于它来构建的,比如我们熟知的Dubbo.Rocketmq.Hadoop等.本文就netty线程模型展开 ...

  5. reactor线程模型_面试一文搞定JAVA的网络IO模型

    1,最原始的BIO模型 该模型的整体思路是有一个独立的Acceptor线程负责监听客户端的链接,它接收到客户端链接请求之后为每个客户端创建一个新的线程进行链路处理,处理完成之后,通过输出流返回应答给客 ...

  6. 性能追击:万字长文30+图揭秘8大主流服务器程序线程模型 | Node.js,Apache,Nginx,Netty,Redis,Tomcat,MySQL,Zuul

    本文为<高性能网络编程游记>的第六篇"性能追击:万字长文30+图揭秘8大主流服务器程序线程模型". 最近拍的照片比较少,不知道配什么图好,于是自己画了一个,凑合着用,让 ...

  7. linux aio 线程,linux AIO (异步IO) 那点事儿

    在高性能的服务器编程中,IO 模型理所当然的是重中之重,需要谨慎选型的,对于网络套接字,我们可以采用epoll 的方式来轮询,尽管epoll也有一些缺陷,但总体来说还是很高效的,尤其来大量套接字的场景 ...

  8. netty socket超时设置_彻底搞懂 netty 线程模型

    编者注:Netty是Java领域有名的开源网络库,特点是高性能和高扩展性,因此很多流行的框架都是基于它来构建的,比如我们熟知的Dubbo.Rocketmq.Hadoop等.本文就netty线程模型展开 ...

  9. linux服务器开发人员必须要彻底理解的关于【Linux】IO的线程模型

    关于IO模型参考:[Linux]五种IO模型 reactor模型应用视频讲解:epoll原理剖析以及reactor模型应用 c/c++linux服务器开发高级架构师免费学习视频点击:C/C++Linu ...

最新文章

  1. OpenCV中minAreaRect()最小外接矩形 cvBoxPoints()计算矩形顶点 RotatedRect和CvBox2D详解
  2. 腾讯AI Lab刷新人脸检测与识别两大测评国际记录,技术日调用超六亿
  3. struts2 理解
  4. MOSS2010单点登录
  5. Win7下面wubi安装Ubuntu14.04LTS
  6. gitlab增加日志
  7. Leecode06. Z 字形变换——Leecode大厂热题100道系列
  8. min里所有的参数都不存在_高中生物所有的考点难点,其实都在你不仔细看的课本里,必修1-3超强记忆手册!...
  9. 信用算力基于 RocketMQ 实现金融级数据服务的实践
  10. javascript挑战编程技能-第九题:数据结构
  11. 用友未获得服务器信息,客户端查询银行日记账没有数据出现,其他客户端和服务器正常...
  12. [大数据之Sqoop] —— 什么是Sqoop?
  13. MySQL(13)-----多表查询(子查询)
  14. Matlab R2016a安装教程
  15. 云计算的未来畅想(五) -- matrix(终篇)
  16. 掌握这几款高保真设计软件,百万年薪不再是梦想
  17. 苹果手机越狱软件_俄罗斯要求 iPhone 预装本国软件,苹果称等同于越狱无法接受...
  18. 【踩坑】Win11 WSL2 中 meld 无法正常使用问题修复
  19. 目前房价、股价下跌。市场出现希望*数市的呼声,请谈请你对救市的看法。
  20. 转:一套大而全的系统架构体系与具体落地方案

热门文章

  1. 量化巅峰对决,“华鑫杯”京东量化大赛等你来!
  2. 《A Graduate Course in Applied Cryptography》Chapter 11 Public key encryption (2)ss-trapdoor function
  3. pythonturtle库使用心得_[python库]turtle库总结
  4. Blender2.8基础三:贴图烘培篇
  5. 前端Vue自定义支付密码输入键盘Keyboard和支付设置输入框Input
  6. 统御项目管理软件(oKit )重大版本更新
  7. Win10远程桌面打开方法有哪些?
  8. 数据结构——有序顺序表的合并
  9. 从盒马鲜生到盒马里,盒马的核心逻辑是什么?
  10. 【从零开始】理解视频编解码技术