libdispatch Grand Central Dispatch 异步并发编程模型 From apple

Slides:



Advertisements
Similar presentations
高级服务器设计和实现 1 —— 基础与进阶 余锋
Advertisements

阻塞操作. 在 linux 里,一个等待队列由一个 wait_queue_head_t 类型的结构来描述 等待队列的初始化: static wait_queue_head_t testqueue; init_waitqueue_head(&testqueue);
While 迴圈 - 不知重複執行次數
藥物濫用 華德學校上午校 黃秀雯.
C语言程序设计 主讲教师 :张群燕 电话:
何谓学龄期 学龄期是指6~7岁入小学起至12~14岁进入青春期为止的一个年龄段。期小儿体格生长仍稳步增长,除生殖系统外其他器官的发育到本期末已接近成人水平。 这个时期发病率较前为低,但要注意预防近视眼和龋齿,矫治慢性病灶,端正坐、立、行姿势,安排有规律的生活、学习和锻炼,保证充足的营养和休息,注意情绪和行为变化,避免思想过度紧张。
第6章 二叉树和树 前面的章节主要讨论的是线性结构,二叉树和树属于非线性的结构。遍历非线性结构比线性结构要麻烦。
第一章 C语言概述 计算机公共教学部.
编译原理上机实习
Chapter 6 時序.
第五章 树 东南大学计算机学院 方效林 本课件借鉴了清华大学殷人昆老师 和哈尔滨工业大学张岩老师的课件.
第二章 JAVA语言基础.
Using C++ The Weird Way Something about c++11 & OOP tricks
Tree(樹) 什麼是「樹」? 「樹」的範例 「樹」的定義 「樹」的表示法.
第三章 堆疊與佇列的基本應用 3-1 簡介堆疊(Stack) 3-2 迷宮問題研究 3-3 佇列(queue)的介紹
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
Kvm异步缺页中断 浙江大学计算机体系结构实验室 徐浩.
第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.
主讲教师:吴琼 微信群:C语言2016 QQ群: 密码scu2016 昵称:“真名+学号”
佇列 (Queue).
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
第3章 C 語言的基本知識.
第 7 章 陣列 (Array).
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
程序设计期末复习 黎金宁
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
cn/~dongeliu/dsa.html 刘 东 信息学院6系 中国科学技术大学
实践演练 广州创龙电子科技有限公司 01 广州创龙电子科技有限公司
辅导课程六.
第十章 C高级程序应用—链表* 10.1链表的基本概念 10.2单向链表 10.3双向链表 10.4应用举例.
进程操作.
第三章 栈和队列.
fp=fopen("CD2.dat","wb"); fwrite(&min,8,1,fp); fclose(fp);
本节内容 模拟线程切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
第七章 操作符重载 胡昊 南京大学计算机系软件所.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
常宝宝 北京大学计算机科学与技术系 数据结构(三) 常宝宝 北京大学计算机科学与技术系
1.3 C语言的语句和关键字 一、C语言的语句 与其它高级语言一样,C语言也是利用函数体中的可执行 语句,向计算机系统发出操作命令。按照语句功能或构成的不 同,可将C语言的语句分为五类。 goto, return.
第1讲 C语言基础 要求: (1) C程序的组成 (2) C语言的标识符是如何定义的。 (3) C语言有哪些基本数据类型?各种基本数
程式結構&語法.
本节内容 随机读取 视频提供:昆山爱达人信息技术有限公司.
C++语言程序设计 C++语言程序设计 第三章 控制语句 第十一组 C++语言程序设计.
实验四、TinyOS执行机制实验 一、实验目的 1、了解tinyos执行机制,实现程序异步处理的方法。
Introduction to the C Programming Language
第四章 栈和队列 栈 ( Stack ) 队列 ( Queue ) 优先队列 (Priority Queue) 小结.
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
Select模型 本节内容 视频提供:昆山爱达人信息技术有限公司 视频录制:yang 官网地址:
信号量(Semaphore).
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.
4-12 外部中斷 HT66F70A.
第二章 类型、对象、运算符和表达式.
本节内容 Lua基本语法.
第二章 基本数据类型 ——数据的表示.
隨機數 (亂數) 10後,取餘數 n = rand(); 利用 Code::Block 驗證一下 n = rand() %10; 998
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
本节内容 Windows线程切换_时钟中断切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
_07多连接之select模型 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
第十二章 位运算.
目录 12.1 位运算符 12.2 位域(位段) 1.
第2章 Java语言基础.
Chapter 2 Entity-Relationship Model
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
第二章 Java基础语法 北京传智播客教育
第六章 直接成本法.
Presentation transcript:

libdispatch Grand Central Dispatch 异步并发编程模型 From apple http://libdispatch.macosforge.org/ chenj@lemote.com

块在其目标队列中被调度执行。 基于队列 任务被拆分成不同的块发往不同的队列。 (一组)块执行完成后,发出通知 队列类型:全局并发队列、main队列、私有串行 队列;

全局并发队列 q = dispatch_get_global_queue( 执行函数complex_calculation 100遍: DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL /* reserved for future use */); 执行函数complex_calculation 100遍: dispatch_apply_f(100, q, user_data, complex_calculation); complex_calculation(user_data, i); /* i ∈ [0, 100) */ 多个complex_calculation同时执行

main队列 串行执行(back up by one thead) q_main = dispatch_get_main_queue(); 全局队列 用来整合苹果Cocoa框架的主线程

私有串行队列 串行执行 q_sum = dispatch_queue_create("com.example.sum", NULL); #define COUNT 128 double sum = 0; void calc_func(void *data, size_t i) { double x = complex_calculation(i); double *sum = (double *)data; dispatch_async(q_sum, ^{ *sum += x}); } dispatch_apply_f(COUNT, q_default, &sum, calc_func);

dispatch_set_target_queue 队列之间的关系 dispatch_set_target_queue 线 程 池 全局 并发 队列 私有队列 main队列 mgr队列 low -overcommit default high

主要的类和继承关系 dispatch_object_s dispatch_continuation_s dispatch_queue_s const void *do_vtable; struct x *volatile do_next; dispatch_object_s unsigned int do_ref_cnt; unsigned int do_xref_cnt; unsigned int do_suspend_cnt; struct dispatch_queue_s *do_targetq; void *do_ctxt; dispatch_function_t do_finalizer; dispatch_continuation_s dispatch_queue_s dispatch_source_s dispatch_queue_attr_s dispatch_source_attr_s dispatch_semaphore_s = dispatch_group_s

dispatch_queue_s 用队列(FIFO)方式容纳dispatch_object_s 正在运行的DO数目:uint32_t dq_running; 队列并发的宽度:uint32_t dq_width; struct dispatch_object_s * dq_items_head NULL DO volatile dq_items_tail

入队操作 _dispatch_queue_push _dispatch_queue_push_list _dispatch_queue_push_list_slow 队列为空 inline NO inline _dispatch_wakeup

出队操作 _dispatch_queue_concurrent_drain_one _dispatch_queue_drain 并发地汲取一个对象返回之 _dispatch_queue_drain 汲取并处理队列中的全部对象 函数调用前先锁定队列: _dispatch_queue_trylock(dq)

块的执行流程 块被封装成dispatch_continuation_s对象 _dispatch_queue_push到目标队列,若目标队列原为空则唤醒之 (_dispatch_wakeup) _dispatch_wakeup(dispatch_object_t dou)作如下工作: 若SUSPENDED,则返回NULL 运行vtable->do_probe,其返回False且队列为空,则返回 NULL _dispatch_trylock(对象锁)失败则返回NULL _dispatch_queue_push(dou.do->do_targetq, dou._do); 最终_dispatch_queue_push到根队列(root queue, do_targetq == NULL)

派发到线程池 _dispatch_wakeup(root queue) _dispatch_queue_wakeup_global vtable->do_probe _dispatch_queue_wakeup_global

派发到线程池 pthread_workqueue_additem_np ( _dispatch_wakeup(root queue) vtable->do_probe _dispatch_queue_wakeup_global int pthread_workqueue_additem_np ( pthread_workqueue_t workq, void *( *workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp)

派发到线程池 pthread_workqueue_additem_np ( _dispatch_wakeup(root queue) vtable->do_probe _dispatch_queue_wakeup_global int pthread_workqueue_additem_np ( pthread_workqueue_t workq, void *( *workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp) _dispatch_worker_thread2 while ((item = fastpath(_dispatch_queue_concurrent_drain_one(dq)))) _dispatch_continuation_pop(item);

执行 _dispatch_continuation_pop is a "dispatch_continuation_s" ? 处理flag: DISPATCH_OBJ_ASYNC_BIT 处理flag: DISPATCH_OBJ_GROUP_BIT dc->dc_func(dc->dc_ctxt) or is a "dispatch_queue_s"? 调用_dispatch_queue_invoke 检查SUSPEND 并锁 队列锁 _dispatch_queue_drain 解 队列锁 解 对象锁 (在_dispatch_wakeup中锁定)

何时wakeup 队列? push到一个空队列时 dq_running为0时 _dispatch_queue_wakeup_global in _dispatch_queue_concurrent_drain_one(派生更 多工作线程)

线程池的实现 使用Darwin线程调用 创建线程池:pthread_workqueue_create_np 依据系统当前负荷决定线程池大小(内核支 持) 添加作业:pthread_workqueue_additem_np 内嵌轻量级的实现 dgq_thread_pool_size指定线程池线程的数量 工作函数:_dispatch_worker_thread 工作线程完成作业后,将睡眠在信号量上若干 秒,直至被唤醒或超时结束进程

其他实现技巧 引用计数的实现 内部引用计数(do_ref_cnt) 外部引用计数(do_xref_cnt) —— 更好的使用错 误侦测 简单有效的内存分配缓冲 只缓冲dispatch_continuation_t对象 per-thread,单向链表 只增不减,直至工作线程结束才全部释放 fastpath, slowpath

Linux的移植 By Mark Heily http://packages.debian.org/squeeze/libdispatch0 附带支撑库: libkqueue (使用epoll, inotify, signalfd, timerfd,实现BSD的kevent接口) libpthread_workqueue (可选,用户态实现了 pthread_workqueue接口)

END