跳到主要內容

發表文章

目前顯示的是有「tips」標籤的文章

Why Linux kernel has ACCESS_ONCE()?

在 LWN 看到 一篇好文章 ,討論Linux kernel 中的 ACCESS_ONCE() macro 的用法與意義。文章討論到 multi-thread 程式共用變數所需要注意的一個細節:要使用 volatile 關鍵字去修飾變數以避免編譯器的最佳化造成的問題。 文中以一個在 Linux kernel 的例子來說明,但考慮到這個議題在任何 multi-thread 程式(或任何有 context-switch 的程式中)都會遇到,所以我用簡單的情況來舉例。考慮某個 thread 有如下程式碼片段: for   ( ;; )   { ...     if   ( global_status  ==  ST_MOVE )   {        do_something ( ) ;     } ... 它會依據 global_status 的值來決定程式流程,而這個變數可能會在另一個 thread function 中被修改(也可能在 signal handler 中被修改),所以每次 loop 時,可能會執行 do_something() 也可能不會執行它。問題在於編譯器的最佳化往往都會作在語言沒有清楚定義的地方。在 C 語言中,由於沒有規定 multi-thread 的共享變數的行為(在 C11 前幾乎對此沒有著墨),所以若 for loop 中沒有對 global_status 任何修改,編譯器有可能將上述 loop 中的判斷整個拿掉: // if global_status is ST_SLEEP for   ( ;; )   { ...     /*    if (global_status == ST_MOVE) {        do_something();    }*/ ... 所以一般要避免這種情況發生,都會以 volatile 修飾 globe_status 變數。這時,我們再來看看 ...

How to debug recursive functions in Python?

Recursive function is the natural way to solve problems when you encounter functional programming. However it is sometimes hard to realize the run-time execution flow even the function is simple. I used to running python debugger and use "commands" to investigate the behavior: ( Pdb )  l    1   - >   def  iseven ( n ) :    2           return   True   if  n ==  0   else  isodd ( n -  1 )    3    4       def  isodd ( n ) :    5           return   False   if  n ==  0   else  iseven ( n -  1 )    6    7       print ( iseven ( 4 ) ) [ EOF ] ( Pdb )  b  2 Breakpoint  1  at /home/mars/ try /python/decorator/use_pdb. py : 2 ( Pdb )  b  5 Breakpoint  2 ...