Understanding C Python GIL

Agenda
1. Thread Models
2. Understanding the Python GIL
3. Thread Safe in C Extension Mode


Inter-Process Communication

[Part 1] Understand IPC

     •What problems to solve by IPC
    •Quick review Windows / Linux IPCs
    •Metro(WinRT) and Desktop on Win8
    •Smartphone Evolution- Android Binder

[Part 2] Multi-Process Design

   •Chrome Multi-Process Architecture and SandBox (IE/Adobe Reader)
   •Parent/Child Windows in Multi-Process

Inside Chrome – Part 1

[Part 1]

•Chromium Application Layers
•Multi-Process Architecture
         – Overview of how the processes communicate and how optimized works
•Sandbox
        –Token / Job Object / Alternate Desktop / IL
        –Java / IE / Adobe

[Part 2]

•Message Routing
       –Control / Routed
•Sample – Video Playback Pipeline
•How GPU Accelerated and HW Render
•Why JavaScript V8 so Fast
•Inter-process Communication (IPC) Basic
      –Named Pipe / Share Memory


MSFT COM

COM目的是為了重複使用元件和定義元件間的相互通訊,為了這個目的也提供了介面規範所以DriectShow, MediaFundation等可以據此開發。而應用程式間當然也可以彼此reuse,就像資料在excel和word之間的傳遞,這就是COM OLE/Automation,另一個例子就是用COM來操控IE,但也因為COM的同步機制導致Google Chrome不願意使用COM而自行用WebKit放棄IE engine.


Python Regular Expression

範例一: 只想要bug的 ID,如DVD123456-0001

import re

ebug = “ebug:DVD123456-0001″

codePat = re.compile(“ebug:([\w-]+)“, re.IGNORECASE)

match = code.search(ebug)

match.groups() = (‘DVD123456-0001’,)

(…) 小括號代表想要取出值的部分

[…] 希望符合條件的集合

\w 只要是數字、英文字跟底線都符合條件相當於[a-zA-Z0-9_]

[\w] 表示 ‘ ‘ 也算是符合條件之一,但順序不一定要在\w之後,也可以為[-\w]

([…]+)表示 […]內符合的字元可以重複發生,所以會命中’D’ ‘V’ ‘D’ ‘1’ ‘2’ ‘3’ ‘4’ ‘5’ ‘6’ ‘-‘ ‘0’ ‘0’ ‘0’ ‘1’。

範例二: 多行文字檔內的各標題內容存取

Text Content:

[what] testsolve ebug:DVD121422-0014

[Why] test resolveHook

[How] dump log

[Risk] none

rv:vinson_hsieh’

(轉成為string變數)

text = ‘[what] testsolve ebug:DVD121422-0014\n[Why] test resolveHook\n[How] dump log\n[Risk] none\nrv:vinson_hsieh’

>>> resolvePat = re.compile(“^\[\s*why\s*\](.*)^\[how\s*\](.*)^\[risk\s*\](.*)", re.IGNORECASE | re.MULTILINE | re.DOTALL)

>>> match = resolvePat.search(text)

>>> match.groups()
(‘ test resolveHook\n’, ‘ dump log\n’, ‘ none\nrv:vinson_hsieh’)

整個pattern是要取出[why][how][risk]三個值,只要字串不match,一個值都不會出來,相當嚴格,

因為有斷行\n所以(.*)必須配合加re.DOTALL把 . 後的 \n 一起涵蓋進來,否則 . 預設搜尋不涵蓋\n而會中斷找不出三個值。

^搭配 re.MULTILINE表示在每行的一開始就一定要是指定的搜尋值,也是比較嚴格的寫法。

\s表示空白可以被涵蓋,\s*表示可以沒有空白或多個連續空白。

比較鬆一點的寫法可以是,

>>> resolvePat = re.compile(“\[\s*why\s*\](.*)\[\s*how\s*\](.*)\[\s*risk\s*\](.*)", re.IGNORECASE | re.DOTALL)

範例三:

reviewerPat = re.compile(“^rv:([\w_]+)?|^reviewer:([\w_]+)",  re.IGNORECASE | re.MULTILINE)

這裡rv:(…)?表示取值可能是 : 或是 : ()? 的意思就是ab+時,結果為a 或ab。所以這裡結果可能為rv: 或是 rv:vinson_hsieh會符合搜尋。但因為取值為小括弧內的值所以為"空值"或"vinson_hsieh"。也就是說可以不填名字而只有rv:當預設時,還是可以有空值被找到。

^rv:([\w_]+)?|^reviewer:([\w_]+),|這裡更簡單就是一般or的意思。也就是你可以寫rv:vinson_hsieh或reviewer:vinson_hsieh。

範例四:

reviewerPat = re.compile(“^rv:([\w_]+)?|^reviewer:([\w_]+)", re.IGNORECASE | re.MULTILINE)

risk = reviewerPat.sub(" “, riskAndReviewer).strip()

由於前面範例二取出的第三個字串實際為risk加上reviewer的相加字串,我們可以倒過來先找出reviwer的值再把它換成空字串,接著去掉空白字串,這樣留下來的字串就是一開頭的risk了。


Must Know about Unicode – Vinson

如果不知道你拿到的字串是什麼encoding其實你不該寫code,直到你懂為止~

看到大家亂七八糟搞不清楚,ASCII/ANSI/Unicode的差別,所以特別做個PPT來說明,希望有幫助。

簡單說ASCII是個沒辦法用在英語系之外的國家,而對應出來的ANSI雖解決了跨國問題,自己國內沒問題了,卻引發出國家間彼此可能看不懂的問題,因為ANSI像沒人管的小孩,所以拿到的人亂parse一通導致亂碼一堆,更慘的是拿到人根本不知道是誰家的小孩,連要確認都沒辦法100%正確,Unicode相對就有家教多了,你會知道該怎麼對應所有國家~ 怎麼做到的,詳見PPT。

Unicode


Multi-thread 的時機

不是任何事拆成多條thread就可以比較快,如果使用的都是CPU bound 那就一點都沒用,但如果仔細分析而可以把GPU/IO相關的code搬出到另一條thread那就會快非常多…問題就在很多人都不仔細看哪些API其實背後是GPU 或 IO 而老是說沒有用….


主題: #define 和 inline 的差異

回覆: #define 和 inline 的差異
« 回覆 #3 於: 2009-06-03 15:11 »

小弟最近在trace一些linux code, 看到了一些令我不解的程式碼…
有些程式碼之中使用
#define function(x) do{…}while(0)
有時又看到使用inline的function,
我一開始以為 #define do{…}while(0) 的寫法等於 inline
後來發現有人的程式裡#define 和 inline穿插使用,
這兩個除了在compile時的差異之外,
想請問各位學長, 在performance上是否有差異和影響, 為什麼要這樣寫?

這樣寫是有特殊用途的,等等解釋。

首先 inline 只有 c++ 才有,linux kernel source 基本上不大可能使用 inline 方式語法,只能夠使用 define 這類 c 與 c++ 都可以支援方式。

define 的許多問題我想大家應該知道,常見像是:

代碼: [選擇]

#define sq(a) (a*a)

這表示自己次方,一般使用上沒問題,像是:

代碼: [選擇]

int answer = sq(5); // 答案是 25

但是這樣用就死了…

代碼: [選擇]

int answer = sq(5+1) // 答案不是 36 啊.....

因為實際上是 5+1 * 5+1 ==> 5+5+1 = 11

所以要改成:

代碼: [選擇]

#define sq(a) ((a)*(a))

在 inline 內這類問題都不會發生就是…

拉回來,至於你說的問題….

代碼: [選擇]

#define function(x) do{...}while(0)
這寫法也是有特殊的意義,記得應該是 linux kernel FAQ 有寫.

代碼: [選擇]

#define swap(x,y) { int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; }
但是這樣使用遇到這種情況會有問題:

代碼: [選擇]

if ( x > y )
swap(x,y);
else
otherthing();

但是程式碼展開就會….

代碼: [選擇]

if ( x > y )
{ int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; };
else
otherthing();

有無看到問題點?

代碼: [選擇]

if ( x > y ) {
int tmp_n ;
tmp_n = x
x = y
y = tmp_n;
}
; <---- 這邊多分號,慘了 ~~~~
else
otherthing();

這導致會編譯錯誤,因為 else 算是多出來的,已經不是與 else 配對的…

基於這個原因,所以才引入 function(x) do{…}while(0) 來解決

#define swap(a,b) do { int tmp_n ; tmp_n = x ; x = y ; y = tmp_n; } while(0)

那展開使用就是

代碼: [選擇]

if ( x > y )
do {
int tmp_n ;
tmp_n = x;
x = y;
y = tmp_n;
} while(0);
else
otherthing();

這樣就不會出包了….

« 上次編輯: 2009-06-03 15:21 由 kenduest »
 記錄
I am kenduest – 小州my website: http://kenduest.sayya.org/


Static function

static PyObject *MyFunctionWithNoArgs( PyObject *self );

當你看到static func時,你會想到什麼? 是的他只能被自己的source file看到,
換句話說他的名字可能就不是那麼重要,因為外面的人看不到...
(這裏其實是因為有另一個mapping table開放出可讀性更高的名字出去)
反過來如果這個func不是要開放給外面的人看,就把它變成static吧...

the names of your C functions can be whatever you like 
as they will never be seen outside of the extension module. 
So they would be defined as static function.

如何在SVN 上找出某個人check in 的comment (for windows)

You may install from below sed for windows and use the command line to query the user name

http://gnuwin32.sourceforge.net/packages/sed.htm

[svn log | sed -n “/XXXX/,/———$/ p"]

XXXX is username.

[svn log -r {2011-12-02}:{2011-12-26} | sed -n “/domain\\username/,/———$/ p" ]