2010年9月30日 星期四

[Linux 小學堂] Linux 的動態連結資料庫使用


轉載自 這裡
前言 :
在 Linux 系統上所執行的程式都會使用到函式庫,而依照應用程式與函式庫連結的方式,可區分為靜態函式庫 (Static Libraries) 及動態函式庫 (Dynamic Link Libraries、Shared Libraries) ,這兩者其實是很好區別的。靜態函式庫 (通常為 xx.a) 裡的函式原始碼需要被編譯到主程式裡頭,所以主程式會顯得比較臃腫些,但好處是該程式可以獨立執行 ﹔動態函式庫 (通常為 xx.so,如您看到的是 xx.so.2.1 之類的,那個 2.1 就是版本囉 ) 則不需整個被編譯到主程式裡邊,只需在程式的原始碼裡設計去呼叫動態函式庫即可。在 Linux 中所執行的程式幾乎都是使用動態連結資料庫.

傳統函式庫位置 :
一般傳統的函式庫是安置在 /lib 及 /usr/lib 目錄中,而提供系統來搜尋的函式庫,其所放置的目錄是定義在 /etc/ld.so.conf 裡。當執行 ldconfig 指令時,會先去讀取 /etc/ld.so.conf,以找出函式庫所放置的目錄位置,然後才能將這些函式庫資料寫入 cache 內,並存放一份在 /etc/ld.so.cache 中。而我們在執行一支程式時,就會由 ld.so 這個動態連結器 (dynamic linker) 程式,到 cache 內去尋找執行程式所需的函式,以提供程式做動態連結.
不過您要是看過 /etc/ld.so.conf,會發現 /lib 及 /usr/lib 並沒有定義在 ld.so.conf 內,因為這兩個目錄是內定值,所以不需要做設定啦 ! 最後如果您有設定 LD_LIBRARY_PATH 這個環境變數的話,其所定義的目錄也會被讀入.

ldconfig 指令介紹 :
如果哪天您函式庫所存放的目錄有所異動,請記得修改 /etc/ld.so.conf,然後再執行 ldconfig 指令,這樣才可以更新 cache 內的資料。以下我們稍作整理:
1. DLL 一般是安置在 /lib 或 /usr/lib 目錄下,而除了這兩個目錄外,DLL 所存放的目錄必須在 /etc/ld.so.conf 或 LD_LIBRARY_PATH 中做定義。

2. 執行指令 ldconfig 時,會先去讀取 /etc/ld.so.conf,然後將 DLL 讀入 cache,並紀錄一份在 /etc/ld.so.cache。當執行程式在執行時,ld.so 就會根據 cache 來找出並載入程式所需的函式庫,以讓程式能正確的執行。

3. 欲瀏覽 /etc/ld.so.cache 內的資料,可執行:
suse:~ # ldconfig -p

4. 增加、減少、刪除部份 DLL 或 DLL 目錄有異動,就須執行 ldconfig,以更新 cache 的資料。

5. 系統於開機時,預設就會執行 ldconfig,以確保 cache 內的資料是最新的。

至於要查詢所執行的程式使用了哪些 DLL,則執行 ldd 指令即可 :
linux-tl0r:~ # which fdisk <先查出指令的位置>
/sbin/fdisk
linux-tl0r:~ # ldd /sbin/fdisk <檢查程式所使用的 DLL>
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/libc.so.6 (0xb7669000)
/lib/ld-linux.so.2 (0xb77e1000)
This message was edited 2 times. Last update was at 15/06/2010 16:51:09

[ Java設計模式 ] 多線程設計模式 : Thread-Per-Message Pattern (這個工作交給你了)


前言 :
上司把文件交給下屬, 指示”能幫我傳真這份文件嗎?”, 妻子對先生說”老公, 幫忙倒一下垃圾喔”. 一個人將工作拜託別人去做, 是很常見的事. 拜託別人 “這件事交給你搂” 以後, 就回來繼續做自己的事. 這章要學習的是 Thread-Per-Message Pattern. 解釋過來就是每個消息一個線程. Message 這裡可以看做是 “命令” 或 “請求” 的意思. 對每個命令或請求分配一個線程, 由這個線程執行工作, 這就是 “Thread-Per-Message Pattern.”
在使用 Thread-Per-Message Pattern 時, “委託消息的一方” 與 “執行消息的一端” 會是不同的線程.


Thread-Per-Message Pattern 的所有參予者 :
* Client (委託人) 參予者 :
Client 參予者會對 Host 參予者送出請求. Client 參予者並不知道 Host 參予者會如何實現這個請求. 範例程序中 Clinet 參予者是 Main 類.

* Host 參予者 :
Host 參予者收到 Client 參予者的請求, 會建立新的線程並啟動它. 這個新的線程會使用 Helper 參予者. “處理” 這個請求. 範例程序中, Host 參予者是 Host 類.

* Helper 參予者 :
Helper 參予者會對 Host 參予者提供 處理請求 的功能. Host 建立的線程會使用 Helper 參予者. 範例程序中 Helper 參予者是 Helper 類.
* Thread-Per-Message Pattern 示意圖
 


使用範例 :
在這裡要寫的範例程序中, Main 類會委託 Host 類顯示文字. 而Host 類會啟動線程來處理這項委託工作. 啟動的線程會使用 Helper 類來進行顯示操作.
* Main 類 :
Main 類會建立 Host 物件而後調用 Host 物件的 request 方法, 代碼如下 :
  1. package dp.thread.ch7;  
  2.   
  3. public class Main {  
  4.     public static void main(String args[]) {  
  5.         System.out.println("main BEGIN");  
  6.         Host host = new Host();  
  7.         host.request(10'A');  
  8.         host.request(20'B');  
  9.         host.request(30'C');  
  10.         System.out.println("main END");;  
  11.     }  
  12. }  
* Host 類 :
Host 類中, 在request方法中啟動新的線程. 實際的處理委託操作則由該線程負責. 代碼如下 :
  1. package dp.thread.ch7;  
  2.   
  3. public class Host {  
  4.     private final Helper helper = new Helper();  
  5.   
  6.     public void request(final int count, final char c) {  
  7.         System.out.println("    Request("+count+", "+c+")BEGIN");  
  8.         new Thread() {  
  9.             public void run(){  
  10.                 helper.handle(count, c);  
  11.             }  
  12.         }.start();  
  13.         System.out.println("    Request("+count+", "+c+")END");  
  14.     }      
  15. }  
* Helper 類 :
Helper 類提供了handle 方法, 用來將字符顯示指定次數. 代碼如下 :
  1. package dp.thread.ch7;  
  2.   
  3. public class Helper {  
  4.     public void handle(int count, char c) {  
  5.         System.out.println("    Handle("+count+", "+c+") BEGIN");  
  6.         for(int i=0;i
  7.             slowly();  
  8.             System.out.print(c);  
  9.         }  
  10.         System.out.println("");  
  11.         System.out.println("    Handle("+count+", "+c+") END");  
  12.     }  
  13.   
  14.     private void slowly(){  
  15.         try{  
  16.             Thread.sleep(100);  
  17.         }catch(InterruptedException e){  
  18.             e.printStackTrace();  
  19.         }  
  20.     }  
  21. }  

使用時機 :
* 提升響應性, 降低延遲時間 :
使用 Thread-Message Pattern, Host 參予者對 Client 的響應性會變好, 延遲時間會下降, 尤其是當 handle 的操作很花時間或是 handle的操作需要等待 I/O 時, 效果特別明顯.
* 適合在操作順序無所謂時:
Thread-Message Pattern 中, handle 方法執行的順序, 並不一定是以調用 request 的順序來決定. 所以操作順序有要求時, 不適合使用此Pattern.

* 不需要返回值時:
在此Pattern, request 方法不會等待 handle 方法執行的結果. 也就是說 request 方法拿不到 handle 方法的返回值. 需要得知處理結果時, 可以使用 Future Pattern 應用.
* 在服務器的製作 :
為了使服務器可以用來處理多數請求, 可以使用 Thread-Per-Message Pattern. 客戶端送達請求, 由主線程接收. 而實際處理該請求, 則交給其他線程處理, 服務器的主線程則回到繼續等待其他客戶端請求的狀態.


補充說明 :
1. Future Pattern :
Thread-Per-Message Pattern, 會啟動新的線程來進行處理. 但送出的請求的線程不會等待實際操作完成, 故無法獲取處理結果. 而在 Future Pattern 會事先建立用來存放返回值的物件. 當處理操作完畢的線程結束時, 會將值寫入 Future 參予者. 當送出請求需要用到返回值時, 才用 Future 參予者讀取.

2. Worker Thread Pattern :
Thread-Per-Message Pattern 中, 每個請求都會啟動一個線程. 在 Worker Thread Pattern 中則會預先啟動足夠數量的線程, 並重複使用這些線程, 提升程序的執行效率.
This message was edited 2 times. Last update was at 07/01/2010 17:49:28

[ Py DS ] Ch3 - Data Manipulation with Pandas (Part5)

Source From  Here   Pivot Tables   We have seen how the  GroupBy  abstraction lets us explore relationships within a dataset. A pivot ta...