2015年1月26日 星期一

Install JDK on Ubuntu

1. openjdk
      $ sudo apt-get update
      $ sudo apt-get install openjdk-7-jdk

2. sun java
      http://askubuntu.com/questions/253039/how-can-i-uninstall-my-current-java-and-install-sun-java-1-6

3. 手動設定JDK
      http://lnmcc.net/2013/03/28/android%E7%BC%96%E8%AF%91%E9%94%99%E8%AF%AF-android-the-correct-version-is-1-6/

4. update the default Java version by running:
     $ sudo update-alternatives --config java
     $ sudo update-alternatives --config javac

     $ sudo update-java-alternatives -s <jname>

2015年1月22日 星期四

[轉] Thread-Safe的理解與分析


何謂thread-safe? 這個問題我看過許多論壇都有討論過,都總讓人覺得不很滿意。在此,筆者想要用更logical的方式來把議題說清楚。首先,我們要了解它的定義! 定義若都不明白就難以判別安不安全了!

thread是什麼呢? 可能也有人不太了解。就從這裡開始… 當cpu處理一段(區塊)的程式碼時,從開始的第一行程式碼來跑就算是thead的開始,直到區塊的最後一行程式結束,就算是thread的結束。所謂的「主thread」,在dos (或dos like)程式裡,就是指main( )這個函式的開始到結束的一個thread。而主thread以外的一個子thread則是指程式人員自行在主thread裡再定義一個「程式區塊」,並請cpu同步的去執行那個區塊。

由上面的thread的定義來看,我們可以進而推論所謂的multithread這個字其實是有三種情形的,哪三種呢?
1/ 相同的一個程式區塊,請cpu"分出多身"來執行它! (一段code被new或說create成數個thread)
2/ 不同的程式區塊,請cpu各別分時的去執行每個區塊 (幾段code個別被new或說create成個別的thread)
3/ 混合以上二種情形

所以,當我們在討論多緒/多線程(multithread)的問題時,我們要先去了解問題是上面三類的哪一類。若是第一類,那就要注意若有使用全域變數,那就極有可能是不安全的。若是第二類,那也要考慮是否不同的thread code是否有共用某同一個全域變數。

我們再把「程式區塊」給解析一下。它可以是一個function,或是一個class(裡面有成員函式),或是上述二者的混合體。因為function或是class都會使用到變數,於是多緒時變數的共享就成了一個很大的問題。這就是為什麼會有thread-safe的這個議題了!

到此為止,我們可以想像若一個程序(process / 主thread)裡,有大於等於一個子thread在跑,就會產生thread-safe的問題。以最簡單的情形來說,mainthread+user自定的一個thread。假設Button元件按下後會刪除memo元件裡某個String,而同時間的一個thread則會取用memo裡的String。假想當thread在取用memo中某String做分析的時候,user不知情的按下button,那麼thread是否有可能會取到不正確的String?  若不經過特別的安全設定,肯定「取用」時時而會出問題!

因此,到底安全或不安全的根源就在那執行的區塊程式碼上了(以上例就是取用的過程)。我要補充一個重要的事,其實每一個thread都有自己的一個專屬stack,所以auto級(local)的變數是不會有共享的問題,因為它們都是存放在thread各自的記憶體空間內,彼此不甘擾。也就是說,若你的程式區塊中,所有使用到的變數都是local(auto)變數,那你這個區塊,或說這個thread,就算是thread-safe !! 相反的,若你的區塊中有用到全域的變數,那麼你的這個thread就有可能是不安全。請注意看,是有可能,並非一定是。

如何把含有全域變數的thread分析出安全或不安全? 其實這是很直覺的。比如說某全域變數int g被數個thread使用到,但每個thread裡只引用到一次,那算安全嗎?  答案是…還算安全(註:極度的嚴僅來說不100%,但98%不為過)。因為單一基本變數的一次存取cpu處理極快,不太會有衝突。又,若是某全域結構體變數 struct tag 被引用存取到一次,那算安全嗎?  答案是…不太安全,因為一個結構體的存取可能涉及到多個微指令。進一步的用上面的例子來說,若int g被「程式區塊」(thread code)引用到2次(含)以上,那就肯定不安全了。比如說第一次是把g設成k,第二次把g再設給某變數i,若thread1正在處理第二次引用,而thread2在處理第一次引用。那thread1可能會得到意外的答案!(g值非它第一次設成的k值,而是變成thread2裡的k值)

如何讓不安全的thread變成安全的?? 其實主要的方法有二類。


1/ 存取共用全域變數時加上lock的機制,而這lock的機制在windows上可以使用mutex、criticalsection、event、semaphore等物件配合WaitForSingleObject或WaitForMultipleObject二個api來控制。其原理就是當某thread在取用資料時,其他的通通都停止並等待,直到該thread取用完。


2/ 把存取全域變數的動作通通交給某一個thread全全處理。比如說你有thread1,thread2,thread3。當要存取全域的struct變數時,thread2就把工作交給thread1做,然後自己停住等thread1完成,thread3也把工作交給thread1做,並等待…  。這原理應該容易理解,因為不安全的工作全都交給"單一"的thread來處理時,那份工作就安全了呀! 當然,這也不禁讓我們覺得,這樣效能非常的差!通通都在等thread1。  不過還好的是,若少少的用還ok,若許多的工作都交給某一thread順序來處理,那就真的沒意義了! 而這種方式其實就是bcb或delphi裡的synchronize這個方法的處理方式! (請看最下面2011年我的補充說明)

 

後註: class 其實也像是一種function,所以class本身也是存在著安全與否的問題。倘若該class裡的menthod有用到全域的變數時,該class也算是不安全的! 而許多的VCL就是這類的class!

註2: 若什麼是auto變數、stack都還不清楚,請先自行google或查程式語言的書,這是很基本且重要但易被忽略的章節。




2015年1月18日 星期日

[轉] Android Binder通信數據結構介紹

http://blog.csdn.net/yangwen123/article/details/9100599

IPC Binder



IPC Binder
1. 基本上是兩個process之間的溝通介面, 也是一種context manager的機制.
2. kernel跑起來之後, 會有binder driver, 之後會有一個process 跑起來叫做ServiceManager, ServiceManager會跟binderdriver註冊為context manager, 負責管理所有的service. 所有的service起來的時候需要跟ServiceManager註冊. 當某個process需要用到某個特別的service的時候, 要透過binderServiceManager詢問某個service, 之後ServiceManager把某個service傳給process. 之後process再透過它取得的的資料再跟service做溝通.
3.  ServiceManger為管理service index的機制
4.  binder主要是透過shared memoryprocess之間做資料的傳輸, 它有一個特殊的功能是可pass file descriptor
5. 所以process可以透過PMEM, ashmem傳資料給另外一個process