【程式語言】WTF Powershell

1
2
3
4
3..4+,2
3..4+2
2+3..4
,2+3..4

以上四句表達式,哪一個是不合法的表達式呢?







答案是第三句 2+3..4,他會噴出以下的 error

1
2
3
4
5
6
方法引動過程失敗,因為 [System.Object[]] 未包含名為 'op_Addition' 的方法。
位於 線路:1 字元:1
+ 2+3..4
+ ~~~~~~
+ CategoryInfo : InvalidOperation: (op_Addition:String) [],RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

一些背景知識

在詳細講解為什麼 2+3..4 會出錯之前,我們首先要理解 powershell 中的四個概念,都很好理解(有學過其他語言的話O_O),分別是

  • create array
  • nested array
  • append array
  • range

create array

要 create 一個 array 很簡單,只要用 , 逗號把數字隔開,像是 1,2,3 這樣,就是一個 array 了,不一定要有括號在外面

nested array

兩個逗號的話,像這樣 ,,1 就是一個兩層的 nested array,等同於 python 的 [[1]]

append array

在 powershell 中,串接陣列是用 +,要 ,2 陣列和 ,3 陣列串接的話就是 ,2+,3,等同於 python 的 [2] + [3]

range

和其他的一些語言(bash, rust, …)一樣,powershell 是採用 .. 來作為 range operator,像是 1..5 就等於 1,2,3,4,5

WTF Powershell

在複習了一些 powershell 的背景知識後,我們就來看看為什麼 2+3..4 會是不合法的表達式,明明對稱的另一個表達式 3..4+2 是合法的阿
首先就運算元的優先序來看,是 , > .. > + 的,所以我們可以把上面的四個表達式寫成

1
2
3
4
(3..4)+(,2)
(3..4)+2
2+(3..4)
(,2)+(3..4)

實際上這四句分別是

  • Object[] + Object[]
  • Object[] + Int32
  • Int32 + Object[]
  • Object[] + Object[]

回頭看一下 error message 你就會發現它其實就是在說不能把 Int32 + Object[]
但是 Object[] + Int32 卻可以,所以他只實作了一個方向的加法? WTF Powershell?
不過換個方向,用 python 的角度來看,他其實像是 a = [3, 4]; a.append(2) 是可以的,但是沒有 a = 2; a.append([3, 4]) 這種寫法

總而言之,因為 Powershell 把 Object[]Object[] 的 concat 和 Object[]Int32 的 append 混著用都是用 + 一個 operator 搞定,所以第一次看的時候會有些頭昏眼花,但其實還勉強算合理,不像隔壁棚的 javascript 群魔亂舞的。Powershell 的部分之後應該還會有更新,大家下集再見。

Read more

【部落格開發】日誌 0x03

部落格要恢復更新啦

距離上次更新也過了一年多了,期間為了更加客製化主題,還想過要自己從頭刻部落格,真是太天真了啊
最後還是回來用新版的 icarus 主題,真香。
之前是把 icarus 主題跟部落格綁在同個 repo 一起更新,但這樣不好管理,所以現在就直接 fork 一份出來維護,是用最版的 5.0.0-rc.1,之後有新版本就再 merge 進來就好了。把之前做過得一些改動都整合進主題了,還是自己客製化過得最對味啊。
之後會慢慢把之前的文章再放回來,應該至少一週一更吧,希望xD

icarus 大改版

我之前用的 icarus 版本還在寫 .ejs
現在已經在寫 .jsx
之前的部落格開發日誌上的程式碼有些可能都不能直接套用了
不過不用擔心我現在已經把我改的程式碼推到 這裡

Excerpt

我發現 icarus 的 excerpt 可以寫在文章內容的開頭,而不用寫在 front matter
中間加一個 <!-- more --> 和文章主體區隔
像是下面這樣,或是看這裡範例

1
2
3
4
5
Hello, this is the excerpt

<!-- more -->

This is the article

這樣 excerpt 也可以快樂寫 markdown
在首頁也只會顯示到 <!-- more --> 之前的內容
但是點 Read More 的按鈕跳進去文章之後,會發現 excerpt 其實還在
只是頁面會捲動到 #more 這個 hashtag 也就是文章主體的開頭
不過這樣感覺只是一個偷懶的作法,不是一個完美的作法

Read more

【部落格開發】日誌 0x02

Admonition

我把 Material for MkDocs - Admonition Extension 搬過來啦,因為實在太好看,就搬過來用了,並且做了下面兩個小改動

  1. border-radius 拔掉了,還是方的好看
  2. 陰影改淡了,感覺比較對
example

這是範例

note

這是範例

abstract

這是範例

info

這是範例

tip

這是範例

success

這是範例

question

這是範例

warning

這是範例

failure

這是範例

danger

這是範例

quote

這是範例

實作

hexo-tag-admonition 借 code 過來改
基本上就是 register 一個新的 hexo tag,然後用到了 detailssummary 這兩個 html5 新的 tag
改的時候有幾個小地方要注意

  1. details tag 原本就有一個箭頭但是很醜,在 summary::-webkit-details-marker 設定 display:none 拔掉他
  2. icon 用到了 font-family: Material Icons,要在 head 裡面加個字體

Code block

另一個改動是程式碼區塊的部分,原來的有點小醜,就改了幾下

  1. 沒有給檔名就不要顯示上面的 header
  2. 可以指定起始行數,以及指定標記特定行數,如下範例
1
python run.py >3,6
run.py >3,6
1
2
3
4
5
6
import math

def main():
print(f'test {math.factorial(5)}')

main()
Read more

【部落格開發】日誌 0x01

部落格架好後,趁熱使用一下各種網站追蹤評測的工具,比如 Google Search Console, Google Analytics, PageSpeed Insights, Sitechecker, Hotjar

Hotjar

記錄使用者點擊的 heatmap

記錄使用者游標移動的路徑

還可以收集使用者的 feedback 回饋,不過載入時間有點久,部落格也不太需要這些資訊,所以就拔掉了,試用一下而已xD

SEO

Defer offscreen images

參考 Lazy load offscreen images with lazysizes,只要載入 lazysizes 這個 scripts 進來,然後把 src 改成 data-src 並加上 class="lazyload" 就好了

註冊個 hexo 的 after_render,把所有 img tag 抓出來改就完事了

scripts/lazy-load-image.js
1
2
3
hexo.extend.filter.register('after_render:html', function (htmlContent) {
return htmlContent.replace(/<img src="([^"]*)" (?:class="([^"]*)")?([^>]*)>/, '<img data-src="$1" class="$2 lazyload" $3>')
});

lazysizes 有 cdn,很方便的

layout/common/scripts.ejs
1
<script src="https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.2.0/lazysizes.min.js" defer></script>

Sitemap

1
npm install hexo-generator-sitemap

裝好 hexo-generator-sitemap 之後,在 _config.yml 加一行收工

1
2
sitemap:
path: sitemap.xml

Robots.txt

直接放在 source/_posts 下面就行了,簡單搞定

Read more

【部落格開發】日誌 0x00

之前的部落格是用 mkdocs,但是 mkdocs 其實是用來生成 document 的,不是拿來生成部落格的,所以文章都沒有日期,也沒有近期文章或是標籤的功能,我之所以選 mkdocs 是因為 mkdocs-material 實在太好看了很對我胃口,不過最近興起了想幫部落格換個皮的念頭,主要是看上了 icarusmaterial-x 這兩個主題,都是 hexo 的主題,最後選了 icarus,然後再自己手動調整,下面會說明一下我手動調整的內容

排版

這個主題整體來說很好看的,但是我不喜歡他的排版,文章只能擠在中間細細長長的,左右兩邊還留了很多空隙,不知道是作者的螢幕太小還是我螢幕太大,所以我把所有 widget 都移到左邊,然後把欄位的比例改成 3:9,css 的部份在 source/css/style.styl:21 把寬度調寬

layout/layout.ejs
1
2
case 2:
return 'is-9-tablet is-9-desktop is-9-widescreen';
layout/common/widget.ejs
1
2
case 2:
return 'is-3-tablet is-3-desktop is-3-widescreen';
source/css/style.styl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
gap = 40px
...
@media screen and (min-width: screen-widescreen)
.is-1-column .container
.is-2-column .container
max-width: screen-widescreen - 2 * gap
width: screen-widescreen - 2 * gap
@media screen and (min-width: screen-fullhd)
.is-2-column .container
max-width: screen-fullhd - 2 * gap
width: screen-fullhd - 2 * gap
.is-1-column .container
max-width: screen-fullhd - 2 * gap
width: screen-fullhd - 2 * gap

Read More

原本 icarus 只有 excerpt 這個選項可以加在文章的 front-matter 中,如下

1
2
3
4
---
title: "部落格開發日誌"
excerpt: 寫一些摘要在這邊
---

但是要每一篇都要自己寫摘要好麻煩,我比較想要的是只顯示固定長度,然後邊邊模糊處理,所以就自己手刻了一個

layout/common/article.ejs
1
2
3
4
5
6
7
8
<div class="card <%= index && (!post.hasOwnProperty('readmore') || post.readmore) ? 'card-readmore' : '' %>">
...
<% if (index && (!post.hasOwnProperty('readmore') || post.readmore)) { %>
<div class="level is-mobile readmore-button">
...
</div>
<% } %>
...
source/css/style.styl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.card-readmore
max-height: 400px
overflow: hidden
position: relative
.readmore-button
position absolute
left: 0
bottom: 20px
width: 100%
display: flex
justify-content center
z-index: 20
&:after
content: ''
position: absolute
bottom: 60px
width: 100%
height: 100px
z-index: 10
background-image: linear-gradient(to bottom, hsla(0, 100%, 100%, 0), hsla(0, 100%, 100%, 0.9))
&:before
content: ''
position: absolute
bottom: 0
width: 100%
height: 60px
z-index: 10
background-image: linear-gradient(to bottom, hsla(0, 100%, 100%, 0.9), hsla(0, 100%, 100%, 1))

Adblock

我本身有在用 AdBlock,然後在用 icarus 主題的時候發現有些物件會憑空消失,比如 back-to-top 那個按了可以回到頁面頂端的小按鈕,後來發現是被 AdBlock 砍了,因為那個小按鈕有 .back-to-top 這個 class,不只 .back-to-top 還有很多關鍵字會被砍,可以看這份 Class and ID to avoid because of AdBlock,那我的解決辦法就是把原始碼裡所有的 back-to-top 改名成 bottom-to-top

就在剛剛,我寫完第一段之後,發現上面的 h2 標題 Adblock 因為 markdown 生成 html 時自動加了 id=Adblock,然後就被 AdBlock 砍了,只好改成自己手刻 html

1
<h2>Adblock</h2>

另一個被砍掉的是 font-awesome 的 icon .fa-instagram,這個就不好改名了,所以我加了一小行 javascript 把 .fa-ig 改成 .fa-instagram,以結果來看我的 script 跑的順序應該是比 AdBlock 來得後面所以沒有被砍

source/js/main.js
1
2
3
4
$(document).ready(function() {
$('.fa-ig').addClass('fa-instagram');
$('.fa-ig').removeClass('fa-ig');
});

Github

mkdocs-material 主題的右上角有顯示 github star 的功能,我覺得很酷,所以就搬過來了

layout/common/navbar.ejs
1
2
3
4
5
6
<a class="navbar-item github-source" href="<%= github.url %>">
<div class="github-source-icon"><i class="fab fa-lg fa-github-alt"></i></div>
<div class="github-source-repository">
<%= github.name %>
</div>
</a>
source/css/style.styl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.github-source
.github-source-icon
padding: 5px
.github-source-repository
padding-left: 10px
font-size: 10px
font-weight: 1000
ul
animation: animateElement linear .3s;
animation-iteration-count: 1;
li
float: left
font-weight: 200
#github-forks
margin-left: 3px

@keyframes animateElement{
0% {
opacity:0;
transform: translate(0px,10px);
}
100% {
opacity:1;
transform: translate(0px,0px);
}
}
source/js/main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
if (typeof (IcarusThemeSettings) !== 'undefined' &&
typeof (IcarusThemeSettings.github.url) !== 'undefined') {
const url = IcarusThemeSettings.github.url
console.log(url)
const matches = /^.+github\.com\/([^/]+)\/?([^/]+)?.*$/.exec(url)
console.log(matches)
if (matches && matches.length === 3) {
const [, user, name] = matches
console.log(user, name)
const api = `https://api.github.com/users/${user}/repos`
const paginate = (page = 0) => (
fetch(`${api}?per_page=100&sort=updated&page=${page}`)
.then(response => response.json())
.then(data => {
if (!(data instanceof Array))
return []

/* Display number of stars and forks, if repository is given */
if (name) {
const repo = data.find(item => item.name === name)
if (!repo && data.length === 30) return paginate(page + 1)

if (typeof repo.stargazers_count !== 'number' || typeof repo.forks_count !== 'number') return []
/* If we found a repo, extract the facts */
return repo
? [
`${repo.stargazers_count} Stars`,
`${repo.forks_count} Forks`
]
: []

/* Display number of repositories, otherwise */
} else {
return [
`${data.length} Repositories`
]
}
})
)
paginate().then(data => {
console.log(data)
const [stars, forks] = data
const facts = $(`<ul class="github-facts"><li id="github-stars">${stars}</li><li id="github-forks">• ${forks}</li></ul>`)
$('.github-source-repository').append(facts)
})
}
}

舊部落格

舊的部落格我還在慢慢搬移當中,所以我把 mkdocs 生成的 html 放進來 hexo 當 static files,只要放在 source/old/ 底下然後在 _config.yml 裡面加一行 skip_render: old/**,hexo 就不會去 render 他了

疑難雜症

在改主題原始碼的過程中,遇到各種奇怪問題時,記得先 hexo clean 一下

Read more

【一秒變時尚】zimfw + powerlevel10k + nord

Zimfw

我也是用了很久的 oh-my-zsh,一直都覺得 terminal 有點慢,不過直到看到這篇 打造屬於你自己的極速 Shell「iTerm + zsh + zim + powerlevel10k」,才有想要換的念頭

zimfw 的優點就是快,雖然他不像 oh-my-zsh 一樣有這麼多內建的插件,但一般的 zsh 插件他也都可以安裝,而且最常用也一定要有的 zsh-syntax-highlight, zsh-completions, zsh-autosuggestions 預設都幫你配置好了,其他插件的安裝請看下面的說明

插件安裝

官方提供的插件在這,archive 預設沒裝,我推薦可以安裝,他跟 oh-my-zshextract 插件是同樣的功能,會自動幫你根據副檔名解壓縮,就不需要再去背那些指令

非官方的插件的話,我們以 alias-tips 這個插件做例子,只要在 .zimrc 加入下面一行

.zimrc
1
zmodule djui/alias-tips

然後打 zimfw install,他就會去幫你 git clone 那個 repo 下來,接著在載入插件的時候會去找 {init.zsh|module_name.{zsh|plugin.zsh|zsh-theme|sh}} 這個格式的檔名,只要找得到這樣的檔案的 github repo 基本上都可以安裝

Powerlevel10k

powerlevel10k 看名字就知道是用來幹掉 powerlevel9k 的,記得當初看到 powerlevel9k 的時候兩眼發光,此生沒看過這麼漂亮的主題,直到現在看到 powerlevel10k powerlevel9k,那 powerlevel10k 究竟是猛在哪,就我來看,我覺得 powerlevel10k 最大的優點在於他優秀的客製化系統,請看下圖

可以讓你一步步設定每個細節,而且不用自己手動去改設定,只要跑 p10k configure 這個指令就好,對懶人十分的友善阿,而且 powerlevel10k 直接推薦我們安裝 MesloLGS NF 字型,裝好就完事了,不需要像 powerlevel9k 還要自己調字型和大小,另一個優點就是速度了,官方說是比 powerlevel9k 快上不少,但是因為我同時也換了 zimfw 所以不知道是不是真的有變快

Nord

顏色的配置我使用 Nord 這款,有冰天雪地高冷的感覺,我把他套用到 kitty, vim, tmux 上,讓整個環境有一致的色調,十分舒服,請看下圖,安裝的部分可以到 官方的 github 裡面去找,各大常見的編輯器幾乎都有支援

Read more

【程式語言】pyc 與他們的產地

pyc 格式

python2

python2 的 magic number 和時間戳記都是 4 bytes

編譯 pyc

import

import 其他的 python 程式的時候,會把被引入的程式編譯成 .pyc 放到 __pycache__ 資料夾
這樣可以減少引入的時間

py_compile

1
2
import py_compile
py_compile.compile('test.py')

就會生成 .pyc 檔在 __pycache__ 資料夾

compileall

1
python -m compileall .

可以一次 compile 資料夾內所有檔案

反編譯 pyc

要 decompile pyc 可以使用 uncompyle6decompyle3pycdc

但是注意到 uncompyle6 對 3.6 版以上的支援沒有很好,可以看 這個 issue,作者沒錢拿也累了,而且新版本又多了新東西,cfg 更難分析,所以 fork 出去了 decompyle3 試圖重新整理並解決問題。

1
uncompyle6 test.pyc
1
2
3
4
5
6
7
8
9
10
11
# uncompyle6 version 3.3.2
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.7.0 (default, Oct 9 2018, 16:58:41)
# [GCC 5.4.0 20160609]
# Embedded file name: /home/oalieno/lib.py
# Size of source mod 2**32: 23 bytes


def f(x):
return x
# okay decompiling lib.cpython-37.pyc

marshal & dis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import marshal
import dis

# PyCodeObject
code = marshal.loads(open('test.pyc', 'rb').read()[16:])
code = compile('x = 1', 'filename', 'exec')

# bytecode
code.co_code

# disassemble PyCodeObject (with line number and some meta data)
dis.dis(code)

# disassemble bytecode (directly)
dis.dis(code.co_code)

用眼睛看 marshal dumps data

可以參考 marshal.c,格式都是一個 byte 的 type 加上後面一段 data,主要的程式碼在這裡 marshal.c line 953,這裡的 r_object 嘗試去讀一個 object 進來,裡面就用 switch case 去處理不同的 type。
比如 TYPE_INT 就是用 r_long 去讀 4 個 bytes 的 long 進來,所以 marshal.dumps(1) 就會長得像 b'\xe9\x01\x00\x00\x00',前面的 type 有時候會被 | 0x80,請看 marshal.c line 223,所以 0xe9 & (0x80 - 1) = ord('i')
另一個像是 TYPE_CODE 就先 r_long 了六次,讀了 argcount, posonlyargcount, kwonlyargcount, ... 進來,接下來才用 r_object 把 code 讀進來 ( 也就是 bytecode ),讀進來的 object 其實是 bytes 型態,也就是 bytecode 是用 bytes 型態存在 code object 裡面的,接下來再繼續把一些 consts, names, varnames, ... 讀進來。


  1. https://docs.python.org/3/library/dis.html
  2. http://unpyc.sourceforge.net/Opcodes.html
  3. https://kdr2.com/tech/main/1012-pyc-format.html
  4. https://late.am/post/2012/03/26/exploring-python-code-objects.html
Read more

【手把手教你玩 Linux Kernel】如何編譯 Linux Kernel

原始碼下載

可以從 www.kernel.org 下載最新的 kernel ( 我是下載 5.0.9 的 )

1
2
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.9.tar.xz
x linux-5.0.9.tar.xz

設置編譯參數

1
make menuconfig

有選單可以客製化,選完之後會產生 .config

編譯

1
make -j$(nproc)

-j 多個程序並行編譯

make help

可以用 make help 看看有哪些參數可以用

安裝

1
make -j$(nproc) modules_install

安裝內核模塊 ( kernel module )
會裝到 /lib/modules/

1
make -j$(nproc) install

安裝內核本體
會裝到 /boot
並且會自動更新 grub
下次重啟系統就會是新的內核

安裝到其他目錄

1
export INSTALL_PATH=/path/to/install


  1. https://www.cyberciti.biz/tips/compiling-linux-kernel-26.html
  2. https://stackoverflow.com/questions/35931157/change-linux-kernel-installation-directory
Read more

【手把手教你玩 Linux Kernel】如何對 Kernel 除錯

編譯 kernel

參考 Compile Kernel

initramfs

1
2
mkdir --parents initramfs/{bin,dev,etc,lib,lib64,mnt/root,proc,root,sbin,sys}
cp `which busybox` initramfs/bin/

busybox 是集成了很多常用 linux 命令的工具
接下來我們需要編輯兩個檔案,initramfs/initinitramfs/etc/passwd

init

tab
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/busybox sh

/bin/busybox mkdir -p /usr/sbin /usr/bin /sbin /bin
/bin/busybox --install -s

mount -t proc none /proc
mount -t sysfs none /sys

ln -s /dev/console /dev/ttyS0

sleep 2

setsid cttyhack su root

poweroff -f

kernel 跑起來的時候會檢查是否有 initramfs,有的話就會把它 mount 在 / 然後跑 /init

passwd

tab
1
root:x:0:0::/root:/bin/sh

打包

1
2
cd initramfs
find . -print0 | cpio --null --create --verbose --format=newc | gzip --best > ../initramfs.cpio.gz

qemu-system

tab
1
2
3
4
5
6
#!/bin/bash
qemu-system-x86_64 -kernel ./linux-5.0.9/arch/x86_64/boot/bzImage \
-initrd ./initramfs.cpio.gz \
-nographic \
-append "console=ttyS0 nokaslr" \
-gdb tcp:127.0.0.1:7777

nokaslr 關掉 kernel 的位址隨機化,方便我們除錯
-gdb 開一個 gdb server 讓我們可以連上去除錯

如何跳出 qemu-system

Ctrl-A X

gdb

1
2
3
4
5
6
7
8
(gdb) target remote :7777
(gdb) set auto-load safe-path .
(gdb) file ./linux-5.0.9/vmlinux
(gdb) apropos lx # 顯示包含 lx 的指令 ( 從 vmlinux-gdb.py 載入的輔助函式 )
lx-cmdline -- Report the Linux Commandline used in the current kernel
lx-cpus -- List CPU status arrays
lx-dmesg -- Print Linux kernel log buffer
...

因為 gdb 會自動載入一些檔案,但有些檔案可能是不可信任的
set auto-load safe-path 就是設定可以信任的路徑,底下的檔案會自動載入,比如說一些 python script
這裡我們要載入的是 ./linux-5.0.9/vmlinux-gdb.py


  1. https://blog.csdn.net/DrottningholmEast/article/details/76651580
  2. https://wiki.gentoo.org/wiki/Custom_Initramfs
  3. http://nickdesaulniers.github.io/blog/2018/10/24/booting-a-custom-linux-kernel-in-qemu-and-debugging-it-with-gdb/
  4. https://blog.csdn.net/chrisniu1984/article/details/3907874
Read more

【程式語言】Python GIL

GIL 解決了什麼問題

每個 python 的物件都有一個 reference count
可以透過 sys.getrefcount 這個函式查看

1
2
3
4
5
>>> import sys
>>> a = []
>>> b = a
>>> sys.getrefcount(a)
3

以上的例子,有 a, bsys.getrefcount 的參數三個 reference
在有很多 threads 的情況下我們必須防止這個 reference count 的 race condition
一個簡單的解決方法就是 GIL

為什麼選 GIL 作為解決方法

就因為簡單易用,讓開發者會想加入開發以及使用它 ( 正因為如此使得 python 這麼熱門 )

那 GIL 為什麼到現在都還沒被拿掉

因為很多提案雖然讓 multithread 效率增加但卻讓 singlethread 變慢了

python 3.2

在 python 3.2 稍微修改了 GIL 的運作機制 ( 小改進 )
原本在有 CPU-bound 和 IO-bound 的 threads 互搶時,IO-bound 要等很久才能拿回 GIL ( 詳情看這篇 )

有 GIL 怎辦

multiprocessing

用 multiprocessing 分許多 process,每個 process 會有獨立的 interpreter 和 memory space ( 不會有因為 GIL 卡住的問題 )
但是 multi-processing 比起 multi-threading 會有額外的 overhead

Alternative Python interpreters

可以用其他實作版本的 python interpreters
比如 Jython 和 IronPython 沒有 GIL


  1. https://realpython.com/python-gil/
  2. https://www.youtube.com/watch?v=Obt-vMVdM8s
  3. http://dabeaz.blogspot.com/2010/01/python-gil-visualized.html
  4. http://www.dabeaz.com/python/GIL.pdf
Read more