Permalink
Browse files

haskell thread slide

  • Loading branch information...
1 parent 2621f84 commit 43b2d6f4a2f0c410f7e58bcd0021d3876f40048c @yihuang committed Jan 19, 2013

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,211 @@
+=================
+Haskell微线程实现
+=================
+
+:Author: 云悦科技 黄毅
+:Email: yi.codeplayer@gmail.com
+
+论文列表
+========
+
+[http://www.haskell.org/haskellwiki/Research_papers/Parallelism_and_concurrency]
+
+用户线程与内核线程
+==================
+
+* 一对一 (传统线程实现)
+* 多对一 (gevent)
+* 一对多 (并行计算)
+* 多对多 (GHC, GO)
+
+抢占式调度
+==========
+
+* 优点: 避免饥饿
+* 缺点: 关键区域
+
+调度时机
+========
+
+* 在分配内存时
+
+线程同步 MVar a
+===============
+
+::
+
+ data MVar a = Empty | Full a
+
+ takeMVar :: MVar a -> IO a
+ takeMVar Empty = 阻塞
+ takeMVar (Full a) = return a
+
+ putMVar :: MVar a -> a -> IO ()
+ putMVar (Full a) = 阻塞
+ putMVar Empty = 写操作
+
+主要数据结构
+============
+
+* Thread State Object (TSO)
+
+ * 堆栈和少量其他状态
+ * Chunked Stack (默认1K)
+
+ * 自动增长 (生成指令检查堆栈空间)
+ * 自动收缩 (GC)
+
+* Haskell Execution Context (HEC) <-> 系统线程
+
+ * 可以运行时增加数量
+ * 通常对应一条系统线程
+ * 有阻塞外部调用时可能对应多个系统线程
+
+挑战1 - 阻塞的外部调用
+======================
+
+挑战1 - 阻塞的外部调用
+======================
+
+HEC:
+
+* Ownership field, protected by lock.
+* 消息队列
+* 处理外部调用的 thread pool
+
+挑战1 - 阻塞的外部调用
+======================
+
+* 调用前释放HEC Ownership
+* 通知线程池中另一个系统线程,或者创建新系统线程继续调度其他 Haskell 线程。
+* 返回时通过消息队列通知当前系统线程,把自己放到等待线程池
+* 当前系统线程收到消息,再让位给返回线程
+
+FFI语法 (safe/unsafe)
+======================
+
+::
+
+ foreign import ccall safe
+ "sys/epoll.h epoll_wait"
+
+ foreign import ccall unsafe
+ "sys/eventfd.h eventfd"
+
+实现多播IO
+===========
+
+实现多播IO 调用者
+=================
+
+::
+
+ recv :: Handler -> Int -> IO String
+ recv fd size = do
+ threadWait EventRead fd
+ c_recv fd ...
+ ...
+
+实现多播IO 调用者
+=================
+
+::
+
+ threadWait :: Event -> IO ()
+ threadWait evt = do
+ m <- newEmptyMVar
+ registerFd fd evt $ do
+ putMVar m evt
+ takeMVar m
+
+实现多播IO 另一种调用者
+=======================
+
+::
+
+ recv :: Handler -> Int -> IO String
+ recv fd size = do
+ ret <- c_recv fd ...
+ if ret==WOULDBLOCK then do
+ threadWait EventRead fd
+ c_recv fd ...
+ ...
+
+实现多播IO IO管理器
+===================
+
+::
+
+ forever $ do
+ events <- poll [socket 和 控制命令的管道]
+ 处理timer
+ 调用events对应的回调
+
+挑战2 异步异常
+==============
+
+::
+
+ throwTo threadId Exception
+
+* 用处: timeout 100 long_task
+
+挑战2 异步异常
+==============
+
+::
+
+ bracket open close process = do
+ a <- open -- 打开资源
+ _ <- try (process a) -- 处理,并忽略所有异常
+ close a -- 关闭资源
+
+* 问题:异常可能在 open 和 try 之间抛出
+
+挑战2 异步异常
+==============
+
+::
+
+ bracket open close process =
+ mask $ \restore -> do
+ a <- open
+ r <- restore (process a) `onException` close a
+ _ <- close a
+ return r
+
+挑战2 异步异常
+==============
+
+::
+
+ timeout :: Int -> IO a -> IO (Maybe a)
+ timeout n io = do
+ pid <- myThreadId
+ timer <- forkIO $ do
+ threadDelay n
+ throwTo pid KillThread
+ a <- io
+ throwTo KillThread timerThread
+ return (Just a)
+
+性能
+====
+
+[https://gist.github.com/4045809]
+
+* 0.3s 创建10万条线程
+
+ 10X faster than gevent
+
+* 10万条线程占用184M内存
+
+ 3.2X less memory usage than gevent
+
+论文列表
+========
+
+[http://www.haskell.org/haskellwiki/Research_papers/Parallelism_and_concurrency]
+
+Thanks
+======
@@ -0,0 +1,2 @@
+all:
+ ../../../huangyilib/s5/rst2s5.py haskell-thread.rst haskell-thread.html
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,25 @@
+/* This file has been placed in the public domain. */
+/* The following styles size, place, and layer the slide components.
+ Edit these if you want to change the overall slide layout.
+ The commented lines can be uncommented (and modified, if necessary)
+ to help you with the rearrangement process. */
+
+/* target = 1024x768 */
+
+div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}
+div#header {position: fixed; top: 0; height: 3em; z-index: 1;}
+div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}
+.slide {top: 0; width: 92%; padding: 2.5em 4% 4%; z-index: 2;}
+div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}
+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
+ margin: 0;}
+#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em;
+ z-index: 10;}
+html>body #currentSlide {position: fixed;}
+
+/*
+div#header {background: #FCC;}
+div#footer {background: #CCF;}
+div#controls {background: #BBD;}
+div#currentSlide {background: #FFC;}
+*/
@@ -0,0 +1,42 @@
+<public:component>
+<public:attach event="onpropertychange" onevent="doFix()" />
+
+<script>
+
+// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com
+// This is licensed under the GNU LGPL, version 2.1 or later.
+
+// This must be a path to a blank image. That's all the configuration you need here.
+var blankImg = 'ui/default/blank.gif';
+
+var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
+
+function filt(s, m) {
+ if (filters[f]) {
+ filters[f].enabled = s ? true : false;
+ if (s) with (filters[f]) { src = s; sizingMethod = m }
+ } else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
+}
+
+function doFix() {
+ if ((parseFloat(navigator.userAgent.match(/MSIE (\S+)/)[1]) < 5.5) ||
+ (event && !/(background|src)/.test(event.propertyName))) return;
+
+ if (tagName == 'IMG') {
+ if ((/\.png$/i).test(src)) {
+ filt(src, 'image'); // was 'scale'
+ src = blankImg;
+ } else if (src.indexOf(blankImg) < 0) filt();
+ } else if (style.backgroundImage) {
+ if (style.backgroundImage.match(/^url[("']+(.*\.png)[)"']+$/i)) {
+ var s = RegExp.$1;
+ style.backgroundImage = '';
+ filt(s, 'crop');
+ } else filt();
+ }
+}
+
+doFix();
+
+</script>
+</public:component>
@@ -0,0 +1,8 @@
+/* This file has been placed in the public domain. */
+/* DO NOT CHANGE THESE unless you really want to break Opera Show */
+.slide {
+ visibility: visible !important;
+ position: static !important;
+ page-break-before: always;
+}
+#slide0 {page-break-before: avoid;}
@@ -0,0 +1,16 @@
+/* This file has been placed in the public domain. */
+/* Don't change this unless you want the layout stuff to show up in the
+ outline view! */
+
+.layout div, #footer *, #controlForm * {display: none;}
+#footer, #controls, #controlForm, #navLinks, #toggle {
+ display: block; visibility: visible; margin: 0; padding: 0;}
+#toggle {float: right; padding: 0.5em;}
+html>body #toggle {position: fixed; top: 0; right: 0;}
+
+/* making the outline look pretty-ish */
+
+#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;}
+#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;}
+
+.outline {display: inline ! important;}
Oops, something went wrong.

0 comments on commit 43b2d6f

Please sign in to comment.