發表文章

目前顯示的是 五月, 2012的文章

atexit() 和 exit() 的注意事項

有時候程式不正常結束時, 希望透過 atexit() 最做低限度的善後程續。但試用的結果是, atexit() 本身滿好用的, 正常結束後會符合預期做事。但是呼叫 exit() 隱藏的問題, 卻不那麼直覺。 目前遇過兩個狀況: 在 signal handler 內使用 exit(): 想在收到異常通知時透過 exit() 善後。結果可能會讓程式卡住掛不掉。這也許和註冊的 callback 做什麼事有關。不過 exit() 不是 async-signal-safe functions (見 man 7 signal), 文件也提到在 signal 內用非 async-signal-safe functions 的行為是未定義的, 所以這種狀況出包也沒什麼好探究的了。 multi-thread 的處理: 註冊的 callback 裡有和 thread 相關的善後機制, 然後在錯的 thread 裡或錯的時機呼叫 exit() 造成 dead-lock。當狀況異常想呼叫 exit() 時, 其實也沒太多心力將 thread 之間的行為弄得更好。 另外關於 _exit(), man page 提到它不會呼叫 callback, 但有一些 implementation dependent 的行為, 感覺上不怎麼踏實。可以確定的是, _exit() 會關掉 file descriptors 而可能造成未知的延遲 (文件又提到可用 tcflush 避免這點, 但看不懂到底是有效還是 implementation dependent)。所以若要確保程式會立即結束, 用 abort() 或 kill(getpid(), SIGKILL) 應該比較穩吧, 只是就無法提供 exit status 了。

Android 的 audio delay

遇到這問題後上網查了一下, 結果發現哀鴻遍野, 許多人提到 audio 從播放到真的出來, 有 500ms 的延遲。我以為聲音播放下去應該要立即出來的, 沒想到有這麼嚴重的延遲。 目前沒有對策, 只好從一堆討論中, 挑了幾個比較有代表性的連結備忘:官方 ticketIssue 3434 - android - need NDK support for real-time low latency audio; synchronous play and recordg 這個放了快三年了Issue 22517 - android - Audio latency is too high! 這個將標題寫得更清楚, 並 highlight 一下上面那個 issue 沒人理 在官方 issues 裡搜 audio latencyaudio delay 會看到更多相關 issues其它來源這兩篇是 2011 年底寫的, 提到最佳 Android 裝置也有 100ms 的延遲, 並且有附聲音和影片展示 audio 延遲是怎麼一回事 (*1)。Musique tactile » Android is far behind iOSMusique tactile » More thoughts on audio latency in Android 這個站提供測試軟體和各裝置測出來的數據, 這裡有人提到運作的原理是播出聲音後用內建麥克風錄回聲音, 藉此算出 audio delay。以這麼高的延遲時間來說, 應該可忽略計時中間的一些 overhead。我用 Galaxy Nexus 測出來的數據會在 200ms ~ 500ms 之間跳來跳去。AndroidLatency — PD Community Site備註*1 可怕的是, 我習慣這些延遲行為後, 竟然覺得第二個影片的展示感覺還好。這或許也可解釋開發者感受到的問題嚴重程度, 有時不如使用者高, 因為開發者已習慣這樣的表現, 或潛意識覺得這很難處理, 因此反應比較遲頓。2012-05-26 更新ScottG+ 上回了不少相關知識, 貼到這裡備忘: (後退一步,講些對你解問題無立即幫助的觀察) 1. 在簡單的 interrupt driven PCM samples 播放運作中,系統 wakeup 次數與 audio de…

iPhone 網路緩慢的原因

最近測一些網路連線的東西, 發覺 iPhone 4S 的行為硬是和各版的 iPad 不同, 照理說 iPhone 4S 比 iPad 新這麼多, 應該表現要更好才對。最後懷疑是無線晶片的問題。查了一下, 發覺不少人抱怨 iPhone 的網路問題, 甚至有人的情況是 Wi-Fi 的表現比 3G 糟。 去除 iOS 裝置的無線晶片良率問題 (*1), 原因大致上有兩種 網路晶片的參數和無線 AP 有衝突, 修改 AP 參數後可改善 網路晶片有省電功能, 會視負載率調整效能 第一點我沒打算嘗試, 從 app 的開發者來說, 就算我的 iPhone 因此變快但使用者的不會自動受惠, 也沒什麼意義。針對第二點做了些實驗, 發覺 MacBookAir、iPad 各型和 iPhone 4 和 4S 都有省電功能, 只是省電的作法有差, iPhone 的效能相對地不穩。 我的測試方法是 下載 Ping 之類的 free app (我用 Network Ping Lite), 用 iOS 裝置 ping 區網或外面的機器, 比較 round-trip time。結果 iPhone 4S 可到 >400ms, 但桌機 <200ms。 由 Network Ping Lite 得知 iOS 裝置的 IP, 用桌機 ping 在同一個區網下的 iOS 裝置。比較閒置時的 round-trip time 和使用 YouTube app 時的情況。結果在閒置時也是有較高的 rtt, 到幾百 ms 都有。但大量使用網路時, 表現符合預期, rtt <5ms, 只是偶而會跳出一個上百 ms。 從 OS 角度來看, 網路用得愈兇網路會愈順, 可讓電力用在刀口上。不過從開發者的角度來看, 這表示若希望一直保有 low latency, 要盡可能持續用網路; 或著, app 必須設計成可容許偶而的 low latency。這兩個選項還挺極端的, 不知系統有沒有可能提供選項可建議放寬網路省電機制。 參考資料Why Wi-Fi May Be Slow on Your iPhoneiPhone Wifi high latency in ping times PS * 我強烈懷疑 iOS 的無線晶片良率有問題。我第一個借來玩的 iPad, 它的 Wi-Fi 很不穩, 於是就沒什麼用它。再…

SIGCHLD 和 zombie

關於 zombie zombie: ps 列的 status 為 Z, 表示 process 已結束, 資源也釋放了, 等待 parent process 呼叫 wait/waitpid 回收它的 exit status, 裡面包含 exit code zombie 是無法被 kill 的, 僵屍無敵啊!! zombie 會占據極小的系統資源, 如可 forked 的 process 數不註冊 SIGCHLD = 註冊 signal handler 為 SIG_IGR => OS 會在 child process 掛掉時直接回收, 不會變 zombie 關於 SIGCHLD 收發時機 即使 child process 收到 SIGKILL, 它也不會當下就掛掉而讓 parent process 在當下收到 SIGCHLD。process 得等取得 CPU 時才會「處理」 SIGKILL 而掛掉。總之, 系統不保證 SIGCHLD 收到的時間 child process 正式掛掉後, 當 parent process 取得 CPU 時, 系統會盡快讓它收到 SIGCHLD。換句話說, 若 parent process 被停住的期間「收到」 SIGCHILD, resume 後會立即收到 SIGCHILD SIGCHLD 如同其它 signal, 不會被 queued, 只有保證在有註冊 handler 的情況下, 至少會呼叫一次 handler (細節說明請查: signal mask/block ) 註冊 handler 前收到 SIGCHLD 的話, 不同系統作法不同, 可能會補送也可能不會補送 關於 handler signal handler 會被繼承 (見 man fork 開頭), 所以若 A 有註冊 SIGCHLD 則 A 的 child process 和後續 grandchild process 都有 SIGCHLD handler。寫 handler 時要注意是否能沿用下去, 或是明確在每次 fork 後重設一次 child process 的 signal handler 標準寫法如下, status 裡會記錄許多有用資訊, 見 man waitpid:int status; while ((pid=waitpid(-1, &st…