2010年8月21日 星期六

設定HDMI聲音輸出 (For Windows XP )

設定HDMI聲音輸出
Step 1 : 到[裝置管理員]查看是否有[ATI HDMI Audio]這一項, 用Driver CD重新安裝[ATI HDMI Driver]
Step 2 : 按[開始]選[控制台]
Step 3 : 選[聲音, 語音, 和音訊裝置]
Step 4 : 選[聲音及音訊裝置]
Step 5 : 在[聲音及音訊裝置 內容]
1.選[音訊]
2.選[Realtek HDA HDMI Out]
3.按[確定]
這樣就可以用HDMI聲畫同步輸出, 如果HDMI作音效輸出, 主板後方的音效插孔就會沒有作用, 不能輸出音效.
HDMI output DTS

2010年8月19日 星期四

Linux burn ISO images to Cds and CD-RWs howto

Linux comes with various GUI and command line application to burn ISO images to CDs/CD-RWs. Cdrecord is command line based application used to record data or audio Compact Discs on an Orange Book CD-Recorder or to write DVD media on a DVD-Recorder i.e. it can brun ISO images.

Find out your CDR/W SCSI address/device name

Scan all SCSI devices on all SCSI busses and print the inquiry strings with –scanbus option. This option may be used to find SCSI address of the CD/DVD-Recorder on a system:
# cdrecord -scanbus
Output:
Cdrecord-Clone 2.01a34 (i686-pc-linux-gnu)
Copyright (C) 1995-2004 Jrg Schilling
scsidev: 'ATA:'
devname: 'ATA'
scsibus: -1 target: -1 lun: -1
Warning: Using badly designed ATAPI via /dev/hd*
interface.
Linux sg driver version: 3.5.27
Using libscg version 'schily-0.8'.
scsibus1:
1,0,0 100) 'SONY' 'CD-Writer' '1.0g'
1,1,0 101) *
1,2,0 102) *
1,3,0 103) *
1,4,0 104) *
1,5,0 105) *
1,6,0 106) *
1.7.0 107) *
In above example, my device name is 1,0,0. Now again use the cdrecord command to burn ISO image:
# cdrecord -v -dao dev=1,0,0 file.iso
You can also specify burning speed:
# cdrecord -v -dao dev=1,0,0 speed=8 file.iso

See also:

2010年8月18日 星期三

cbrowser

 

Cbrowser is a graphical C/C++ source code searching and browsing tool, and a hierarchical function call viewer.
Cbrowser is a front end to the popular source code indexing and querying program cscope. It is also designed to work with the free alternative to cscope called cs. This can be obtained at ftp://cantor.informatik.rwth-aachen.de/pub/unix/.
Both of these tools have text based user interfaces, and have limited file viewing capabilities. Cbrowser provides a full featured file browser with syntax highlighing and full text searching.
Cbrowser helps manage the recursive process of searching through source code for usages by providing a history mechanism. Every query is recorded and can be recalled at any time, without the need of re-querying the database.
Cbrowser allows you to build and use multiple source code databases for individual software projects. Switching databases is as simple as selecting the file, and a history of all databases used is kept at all times.
Best of all, cbrowser provides a hierarchical function viewer. Functions may be expanded and contracted to show or hide the functions they call. The function's code itself is shown in an adjoining viewer. This feature is implemented using the megawidget Library by Jeff Hobbs which luckily for me comes with an unrestricted license.


http://sourceforge.net/projects/cbrowser/

2010年8月17日 星期二

vim 的取代置換功能「s」

vim-logo.gif在 前面我們所談的那些可以說是比較基本的東西,但是對於一份文件來說,光有前面所介紹的游標移動、刪除等等功能是不足夠的。面對一份文件我們通常會因為某些 緣故而使得我們必須去修改當中固定出現的字串樣式(pattern)成我們想要的樣子。最常遇到的就像中文文件的標點符號問題,或是 un*ix 和 DOS 文件格式之間轉換常會有個 ^M 結尾會讓人覺得很討厭,又或是我們想要把一份 HTML 格式的文件去除掉它的 HTML tag。
對於這些事情來說,拿中文標點符號置換這個很多編輯器都做得到,簡單地說如果想更動的 pattern 是一個固定的字串,那對於一般編輯器來說都不會太困難,但是對於具有固定格式,但字串內容卻不一定的該怎麼辦?就像要去掉 HTML 格式中的所有 HTML tag?這就是 vim 開始大顯身手的地方了。

今天我們不談別的其他指令,就光談在 vim 中的「 :s 」指令。小寫 :s 表示置換(substitute)的意思,不過通常你用 vim 下 :h :s 指令的時候會看到這樣的畫面:
vim help for :s substitute
其實這一串東西就是在說 :s 這個指令的格式要怎麼下。
Range:
一般對於整份文件都要作置換的話,我都會下像這樣的指令:
:%s/, /,/g
最前面的「%」就是表示全域,也就是現在編輯的這一份文件都要作後面取代的工作。那這個指令就是說要把半形的逗點「,」變成全形「,」。那後面 「g」又代表什麼意思呢?在 g 這個欄位上的東西是用來表示對目前這個指令所做的額外的選項。就拿 g 來說, g 代表在文件中每一個出現的半形逗點都要置換成全形。或許你會問剛剛不是已經用「%」表示全域了嗎,怎麼又要用 g 呢?我應該這樣說,「%」用來表示從文件的第一行到最後一行。但是在比對(match)的時候,如果不加「g」這個額外選項的話, vim 只會把每一行比對到的第一個作取代,同行其他也 match 到的就不管了。所以用「g」表示每一行中每一個比對到的都要置換。
所以同理,如果你要把那些因為 un*ix 和 DOS 之間格式不合所造成的^M消掉的話,也只需要下成這樣就可以了:
:%s/^M//g
可是有時候你想要作置換的只是文件中的某一部份的話怎麼辦?不要緊,還記得選取模式嗎?在你想置換部分的開頭按下大寫「V」然後用移動游標(我們之前講的 vim 移動游標的方法在選取模式下都可以用)到你想要的位置之後按「:」就會跳到輸入指令的狀態,如下圖最下面那行看到的一樣:
vim selection for substitute
當然你很確定行數,你也可以這樣下:
:1,300s/vim/VIM/g
或者是如果你很確定要從現在游標所在行之後的所有行都置換,可以下成:
:.,$s/vim/VIM/g
冒號一開頭的那一小點「 . 」就代表游標現在所在行,「$」則用來表示最後一行。
或許聰明的你已經想到怎麼樣可以從現在所在行之前的都要置換了,
:.,1s/vim/VIM/g
不過當你這樣打的時候, vim 會跳出來一個訊息:
Backwards range given, OK to swap (y/n)?
這就是說你給了一個起始行數比結束行數還要大的範圍。這是因為 vim 所定的範圍都是從小到大,如果你要從大到小不是不行,只是多個訊息確認你沒有打錯罷了。
Pattern:
像前面說,固定字串像把半形逗點換成全形逗點這都還容易,如果只是格式固定,但是字串內容會變動怎麼辦?就像去 HTML tag 的時候就很麻煩。
還記得我們在淺談vim那時候提過的指令嗎?
  • :%s/\n/^V/g
  • :%s/《[^<》]*>//g
  • :%s/^V/\n/g
在中間的那一些 [^<>]*看起來像外星文字的,就是 pattern 比對的主力。事實上關於這些東西,我們在談 vim 的 search 搜尋功能的時候也有提到過一些。所以我們今天就來補一些上次沒有講到的東西。
假如我現在有一筆人名、電話的資料,由於是隨手記的,上面自然就是沒有排序過。那沒排序過對於想要在上面找資料的人就很麻煩。萬一人名記不太清楚, 電話號碼也記得七七八八,雖然說有 vim 方便的 search 功能,但總是感覺不足。(當然這只是假設情況,因為實際上可能大家都已經建立某種方便搜尋的資料庫了)
我們先假設人名、電話的對應長成這樣:
趙大明  1235478982
錢小名  1223450012
王孫李  5938123812
周渚衛  1384914191
沈以情  2345934981
那我可不可以讓它變成這樣子?
1235478982   趙大明
1223450012   錢小名
5938123812   王孫李
1384914191   周渚衛
2345934981   沈以情
我可以下這樣的指令完成這個工作:
:%s/\([^0-9]\{1,}\)\([0-9]\{1,}\)/\2 \1/g
前面橘色的部分 \([^0-9]\{1,}\) 用 \( \) 括起來的,表示這是一個的單元,之後就可以依照它出現的順序而使用 \1, \2,… ,來代表它。所以我們可以看到 [^0-9] 就表示非數字的部分,後面的\{1,} 如果你還記得的話,就是代表出現至少一次。不過這個時候DK長輩會跟你說用 vim 要文明一點,要用「\+」來代表至少出現一次。看個人喜好了,如果你願意多記一些代替的符號就多記一點,你可以用 :h /multi 看到更多這些替代符號。
所以把 pattern 用 \( \) 分開之後,我們就可以用 \1,\2 來把他們交換位置。
不過你可能會說這樣還沒排序啊。我們可以用選取模式把整份文件選起來,或是你懶得用上下左右改變,你可以用 ggVG (gg 跳到第一行之後,用大寫V進入選擇模式,以大寫G跳到最後一行)把整份文件選起來之後按 :!sort,這時候在你 vim 視窗的最底下就會變成這樣:
:’《,’》!sort
按下去就會變成根據每一行的最前頭作排序的結果。所以結果就會變成:
1223450012   錢小名
1235478982   趙大明
1384914191   周渚衛
2345934981   沈以情
5938123812   王孫李
很簡單吧? :p
如果你願意配合暫存器( registers )的話,有時候也能省點力氣。在講 vim search 的時候,我們曾經提了用 搭配數字鍵 0 來把暫存器 0 的東西叫出來。同樣的,我們不管用 / 或是 ? 等等輸入字串的時候,事實上都已經把要搜尋的字串寫入「/」的暫存器裡面,所以當我們只是想置換的字串就是搜尋的字串的話,我們可以這樣做:
:%s//用來取代的字串/g
表示在按 之後按下「/」這個按鍵。這樣就可以把搜尋的字串叫出來並用之於置換指令上。
額外指令:
我們剛剛在前面談到可以作像「g」這些的額外控制。那有哪些控制可以作呢?
比方說在我們作置換的時候,由於 vim 預設是有大小寫的差別,如果你不管大小寫都要取代的話,那可以用「i」這個額外參數來控制 vim 取代的時候就不管大小寫都會作取代的工作。
不過有時候,我們可能不太能確定是不是整份文件中的每一個都要取代,那我們就可以加「c」 confirm 確認參數來控制,那使用上也很容易。 vim 會在比對到之後問
(y/n/a/q/l/^E/^Y)?
  • y 是代表執行目前的取代。
  • n 是跳過。
  • a 代表 always ,就是從目前以後的取代都會執行。
  • q 則是不要作取代,並且離開詢問要不要取代的狀態,並回到指令模式或原來的模式下。
  • l 則是 last 的意思,就是目前這個取代執行後就離開詢問的取代模式,回到指令模式或原來的模式下。
  • ^E 表示往前一頁。
  • ^Y 表示往後一頁。
對於 :s 的用法到這裡我們就已經把常用的幾個方式都說完了。礙於篇幅,我也決定先寫到這裡就好,不然寫一大篇,可能連有興趣進來瞭解 vim 的人光看到就害怕了,怎麼還有辦法體會 vim 的好呢?其實關於 :s 的用法,還有 pattern 還有很多的方式在本篇中沒有提到,你可以在 vim 中用 :h :s 看到更多詳細的資料。今天就來 vim 吧!

from http://greenisland.csie.nctu.edu.tw/wp/2005/09/02/302/
-----------------------------------------------------------------------------------------------------------------------------------------

vi/vim 中可以使用 :s 命令來替換字串。該命令有很多種不同細節使用方法,可以實現複雜的功能,記錄幾種在此,方便以後查詢。

:s/vivian/sky/ 替換當前行第一個 vivian 為 sky

:s/vivian/sky/g 替換當前行所有 vivian 為 sky

:n,$s/vivian/sky/ 替換第 n 行開始到最後一行中每一行的第一個 vivian 為 sky

:n,$s/vivian/sky/g 替換第 n 行開始到最後一行中每一行所有 vivian 為 sky

n 為數字,若 n 為 .,表示從當前行開始到最後一行

:%s/vivian/sky/(等同於 :g/vivian/s//sky/) 替換每一行的第一個 vivian 為 sky

:%s/vivian/sky/g(等同於 :g/vivian/s//sky/g) 替換每一行中所有 vivian 為 sky

可以使用 # 作為分隔符號,此時中間出現的 / 不會作為分隔符號

:s#vivian/#sky/# 替換當前行第一個 vivian/ 為 sky/

:%s+/oradata/apras/+/user01/apras1+ (使用+ 來 替換 / ): /oradata/apras/替換成/user01/apras1/

1.:s/vivian/sky/ 替換當前行第一個 vivian 為 sky

:s/vivian/sky/g 替換當前行所有 vivian 為 sky

2. :n,$s/vivian/sky/ 替換第 n 行開始到最後一行中每一行的第一個 vivian 為 sky

:n,$s/vivian/sky/g 替換第 n 行開始到最後一行中每一行所有 vivian 為 sky

(n 為數字,若 n 為 .,表示從當前行開始到最後一行)

3. :%s/vivian/sky/(等同於 :g/vivian/s//sky/) 替換每一行的第一個 vivian 為 sky

:%s/vivian/sky/g(等同於 :g/vivian/s//sky/g) 替換每一行中所有 vivian 為 sky

4. 可以使用 # 作為分隔符號,此時中間出現的 / 不會作為分隔符號

:s#vivian/#sky/# 替換當前行第一個 vivian/ 為 sky/

5. 刪除文本中的^M

問題描述:對於換行,window下用回車換行(0A0D)來表示,linux下是回車(0A)來表示。這樣,將window上的檔拷到unix上用時,總會有個^M.請寫個用在unix下的過濾windows文件的分行符號(0D)的shell或c程式。

。 使用命令:cat filename1 | tr -d “^V^M” > newfile;

。 使用命令:sed -e “s/^V^M//” filename > outputfilename.需要注意的是在1、2兩種方法中,^V和^M指的是Ctrl+V和Ctrl+M.你必須要手工進行輸入,而不是粘貼。

。 在vi中處理:首先使用vi打開檔,然後按ESC鍵,接著輸入命令:%s/^V^M//.

。 :%s/^M$//g

如果上述方法無用,則正確的解決辦法是: [Page]

。 tr -d \"\\r\" < src >dest

。 tr -d \"\\015\" dest

。 strings A>B
6. 替換確認
我們有很多時候會需要某個字元(串)在文章中某些位置出現時被替換,而其它位置不被替換的有選擇的操作,這就需要使用者來進行確認,vi的查找替換同樣支持
例如
:s/vivian/sky/g 替換當前行所有 vivian 為 sky
在命令後面加上一個字母c就可以實現,即:s/vivian/sky/gc
顧名思意,c是confirm的縮寫

7. 其它

利用 :s 命令可以實現字串的替換。具體的用法包括:

:s/str1/str2/ 用字串 str2 替換行中首次出現的字串 str1

:s/str1/str2/g 用字串 str2 替換行中所有出現的字串 str1

:。,$ s/str1/str2/g 用字串 str2 替換正文當前行到末尾所有出現的字串 str1

:1,$ s/str1/str2/g 用字串 str2 替換正文中所有出現的字串 str1

:g/str1/s//str2/g 功能同上

從上述替換命令可以看到:g 放在命令末尾,表示對搜索字串的每次出現進行替換;不加 g,表示只對搜索

字串的首次出現進行替換;g 放在命令開頭,表示對正文中所有包含搜索字串的行進行替換操作

(原文地址: http://wzgyantai.blogbus.com/logs/28117977.html)

Windows和Linux文件共享新的途徑:Dokan

一、Dokan Library
  如果您想在Windows系統上創建一個新的文件系統的話,例如:改進FAT或NTFS文件系統,您就需要自己開發一個文件系統驅動。 在Windows系統上開發工作在內核模式的設備驅動程序是一件極為困難的事情。 使用Dokan庫(Dokan Library),您可以非常方便地創建自己的文件系統而不需要編寫設備驅動程序。 Dokan庫類似於Linux下的FUSE用戶空間文件系統,但是它工作在Windows下。
  Dokan庫包含一個用戶模式的DLL文件(dokan.dll)以及一個內核模式文件系統驅動(dokan.sys)。 Dokan文件系統驅動一旦安裝,您就可以在Windows上創建和普通文件系統一樣的文件系統。 使用Dokan庫創建的文件系統的應用程序稱為文件系統應用程序。 來自用戶程序的文件操作請求(例如:CreateFile,ReadFile,WriteFile等)將被發送的Windows輸入/輸出子系統(運行在內核模式),請求之後將被發送到Dokan文件系統驅動程序(dokan.sys )。 通過使用Dokan用戶模式庫文件(dokan.dll)提供的函數,文件系統應用程序能夠向文件系統驅動程序註冊回調函數。 文件系統驅動程序在收到請求後調用註冊的回調函數例程來響應請求。 回調函數例程的處理結果將返回給用戶程序。 例如:當Windows資源管理器請求創建一個目錄,請求“OpenDirectory”將發送到Dokan文件系統驅動程序,然後驅動程序將調用文件系統應用程序提供的OpenDirectory回調函數例程。 函數例程的處理結果作為OpenDirectory請求的響應返回給Windows資源瀏覽器。 如此一來,Dokan文件系統驅動程序就如同一個位於用戶程序和文件系統程序之間的代理程序。 使用Dokan庫的好處是,它允許程序員開發更安全也更容易調試的用戶空間文件系統。
二、Dokan SSHFS
  SSHFS(SSH文件系統)是一個文件系統客戶端程序,使用它可以將遠程服務器上的目錄掛載在本地直接訪問。 先前的版本用於輸出SFTP提供的目錄和文件,而當前的版本主要用於安裝有FUSE的系統上。 在用戶訪問服務器資源的過程中,數據通過SSH加密傳輸,安全而高效。
  Dokan是FUSE的Windows實現,使用Dokan SSHFS可以將Linux服務器上的目錄以網絡盤的形式掛載到本地使用,類似於Samba。 要使用Dokan SSHFS需要首先安裝Dokan Library,它們可以在Dokan官方網站下載。

2010年8月15日 星期日

汽車電池概述

目前主要的汽車生產地區為北美、亞洲以及歐洲,在這三個主要地區,都自行制定了一套汽車電池的規範,將尺寸以及性能等級規格化.而這三個主要地區所生產的車輛,皆不分母廠品牌,於車型設計時以及組裝時即考慮到當地地區的制定的電池規範,選擇適用型號作為標準組車零件,例如北美生產製造的TOYOTA Camry及Corolla車型,雖母廠為日系,卻使用ACDelco美規電池為其標準組車零件。


不論美規或日規或歐規電池,在規範上有主要是針對下列幾點做為區分:


1.電極樁頭(正負極)方向位置及大小。

2.尺寸(長寬高)。

3.性能等級(RC/CCA/CA/AH….)。


在這裏我們以美規、日規料號來讓讀者從料號就可解讀電池的規格:


1.美規 - 在台灣經常使用的料號為24-6MF/35-6MF/58-6MF/65-6MF/75-6MF。前面二個數字為電池族類(group),後面MF前的數字為等級。每一族類都被賦予制定的長寬高尺寸,也就是說相同尺寸的電池可以有不同性能等級差異。例如35-6MF性能就要比35-5MF來得好,當然價格也就高上一些。比較特別的是75-6MF的電極樁頭位置是設計在電池側邊,配合車輛整體設計。


2.日規 - 日規電池料號的制定上,亦有其一定的方式。以55B24L為例,"55"為電池的性能等級,"B"為制定的寬度與高度尺寸(約134mm x 225mm),"24"為電池長度(單位公分),"L"為電極樁頭正極的位置方向在右邊。因此,從55B24L這個型號即可瞭解到它的尺寸約為240mm x 134mm x 225mm(長x寬x高)、正極在右(樁頭位置朝上)。


同時在電池正面,我門還可以看到標示出的性能等級,一般都以RC、CCA、CA、AH做為國際性的測定標準。為使讀者能更深入瞭解這些測定標準的意義,進而解讀你車上所安裝或購買的新電池上性能等級,我們也一一說明這些標準的規範。


1.RC - Reserve Capacity儲備能量

儲備能量單位為分鐘。當車輛在發電機失效之後,維持車輛運轉及行駛的所有用電包含冷暖氣、大燈、車窗除霧、雨刷及引擎點火系統等等都是由車上的電池來供應。在北美高緯度地區,溫度相對較台灣來得低,再加上每個城鎮之間距離遙遠,若是在人煙稀少的途中發電機失效,汽車電池又無法維持一段時間的電源供應的話,後果將可想而知。因此國際電池協會(BCI)將此一情形考量後,設計RC標準,簡單來說,若您的電池上標明RC為110MIN,表示您的電池可以在發電機失效下讓車輛繼續行駛110分鐘。


2.CCA - Cold Cranking Ampere冷啟動電流
冷啟動電流單位為安培。一般車輛,尤其是車齡過久的車,往往打馬達時無法順利啟動引擎,必需維持數秒以上或第二次啟動。其實在啟動引擎時是電池電量消耗最多的時後,短時間大電流輸出的瞬間,電池的電壓可以從正常的12.5V下降至10.5V甚至以下。愈大的冷啟動電流對這種啟動不順的情形會有較大的幫助。


3.CA - Cranking Ampere啟動電流

其主要意義與CCA類似,單位同樣為安培,唯一與CCA差異的是測定時之溫度。CCA是在攝氏零下17.8度環境下所得出的結果,CA則是在攝氏零度環境下所得出的結果。若同一個電池上同時標示CCA及CA,CCA的數值會比CA來得低,因為溫度愈低,電池的表現會愈差。


4.AH - Ampere Hour安時

為日本工業標準(JIS)所制定的標準。簡單的說,電池的電壓維持在10.5伏特以上且以一個固定的安培數放電能維持20小時,此一固定安培數乘以小時數即為安培小時。例如以20小時固定5安培放電,則電池的安培小時數為100。


雖然每個測定標準都有一個數值,但電池的實際性能表現是根據實際的使用狀況及環境而有所不同。各種客觀因素如環境溫度、濕度、設計或駕駛人用車習慣都會影響。因此,這些測定結果都只是作為制定電池規範的依據及評定電池性能的等級,以及車廠設計車輛時選定規格的參考。選用正確規格的電池及正確的使用才是駕駛人應該注意的地方。


電瓶資訊補充!!

DIN:Deutehe fndustri Normen,在過液0℃在一定負載下速續30秒經由電壓9V或連續150秒終止電壓6V。
BCI: Bettry Council fnternational過度0℃下或(20℃)在一負載下,速續30秒終止電壓7.2V以上。
IEC:International Electiotechnical 在0℃下(-18℃)在一負載下建續60秒終止電壓在6V以上。
BSR: British Stondaids Rate 在溫度0℃(-18℃)在一定負載下連續180秒,終止電壓在6V以上。

電池的不同定義方式:電池由溫度、電壓和電流(放電)來決定。
依照SAE(Society of Automo tive Engineeers)規定而製成並由BC2(BCI)作成RC(Resevve Capacity)和CCA(Cold Cranking Amperes)來定義電池規範。

CA: Crarkiy Amperes(BCI ratiy)充飽電池電池在過液32(℃)連續30秒在一定的負載下終止。
RC: Reserre Capaciz,在80℉,25內負載下終止電壓在10.5V,可維持時間(以分鏡計)。
CCA:Cold Crankiy Amperes,在0℉(-18℃)以一定負載下速供30秒經由電壓在7.2V以上所得數據。
AH: Ampere Hour(20hr rate),以一個20hr rate 100AA的電池在負載5A可維持20小時(100AA/20 =5A),經由電壓10.5V,溫度80℉。
MCA: Merine Crankriy Amps,在0℃(32℉)速續30秒終止電壓在10.5V以上在一定負載下

2010年8月11日 星期三

Concurrent Programming

何謂 Concurrent Programming ??

所謂的 Concurrent Programming 簡單的講就是一個多工的程式, 這種形式的程式設計有個好處就是當程式 Block 的時候,程式還能 繼續做其他的事,通常 Block 的情況最常發生於網路程式或是一些和 I/O 做處理的程式,一般 Concurrent Programming 最常用的方法就是 用 fork() 還有 thread 這兩種功能,下面將討論這兩種方法。

關於 UNIX 下的 fork()

在 UNIX 中有所謂的 fork() 功能,這個功能主要目的是產生兩個 一模一樣的 process 在電腦中同時執行,藉由這種方法可以做出 Concurrent Programming 的效果,這種方法在 UNIX 一直都被廣泛的應用在各種不 同的應用程式上。

#include &ltstdio.h>

void main(void)
{
  int pid,i;

  pid = fork();
  if (pid == 0) {
     for (i=0;i<44;i++) {
       printf(" I am a child process I say %d\n",i);
       sleep(1);
     }
     exit(1);
   }
  else if (pid > 0) {
     for (i=0;i<40;i++) {
       printf(" I am a parent process I say %d\n",i);
       sleep(1);
     }
  }
  else if (pid < 0)
 printf(" Sorry .....I can't fork my self\n");
}
上面就即是一個簡單的 fork() 用法,執行上面的程式後, 可以藉由印出的字串看到多工的效果,fork() 還可配合 exec() dup() pipe() 做出和外部程式結合使用的效果。再來就解釋一下 fork() 是怎麼動作的:
原來的 process
   +---------+
   |  Data   |
   +---------+
   |  Code   |---> PC
   +---------+

  執行 fork() 之後

  原來的 process                    fork 出來的 process
   +----------+  複製 Data Code 到     +----------+
   |  Data    | ===================>  |   Data   |
   +----------+                       +----------+
   |  Code    |---> CP = CP+1;        |   Code   |----> CP = CP+1
   +----------+                       +----------+
由上圖可以看出原來的 process 和 fork 出來的 process 不論是變數、程式 碼都是一模一樣的,唯一不同的是 fork() 的返回值,parent process 的返回值 是 child process 的 PID ,而 child process 的返回值是 0 ,因此在程式實 作上就以 fork() 的返回值來判斷那一個是 parent 那一個是 child 。

關於 thread

thread 是最近較為流行的一種趨勢,thread 可分為兩種:user-level 和 kernel-level,這兩種方法各有其優缺點,以下是他們的比較:

The advantages of kernel-level threads over user-level threads are:

- supports multiprocessors;

- possibly smoother scheduling, since the same scheduler (the kernel's)
  handles both threads and other Unix processes;

- no special action needed to make blocking system call suspend only
  the calling thread, not all threads of the process (user-level
  threads usually rely on a combination of select() and jacketing of
  C library functions for system calls);

- as a consequence of the above, more efficient I/O and
  timer-based operations (no need for extra select() and gettimeofday()).

The disadvantages are:

- more expensive context switches between threads, at least when blocking
  on conditions and mutexes;

- thread creation is more expensive.

                                                        --- 引自 LinuxThreads --
由上面的比較可以清楚的發現 kernel-level 是一個比較好的選擇, 也算是發展的趨勢吧,下面舉個在 Solaris 下的 thread 範例:

#define _REENTRANT
#include &ltthread.h>
#include &ltstdio.h>
#include &ltstdlib.h>

#define         NUM_THREADS     10
#define         SLEEP_TIME      10

void    *sleeping(char *);
int     i;
thread_t        tid[NUM_THREADS];

void main(int argc,char *argv[])
{
        for (i=0;i&ltNUM_THREADS;i++)
                thr_create(NULL,0,sleeping,"4",0,&tid[i]);
        while (thr_join(NULL,NULL,NULL) == 0)
                ;
        printf("main() reporting that all %d threads have terminated\n",i);
}

void *sleeping(char *sleep_time )
{
        printf(" thread %d sleeping %d seconds\n",thr_self(),atoi(sleep_time));
        sleep(atoi(sleep_time));
        printf("\n thread %d awakening\n",thr_self());
}
compile 的時候記得要加 -lthread 以這個程式和上面 fork 中所舉的例子來做 比較可明顯的發現 thread 所佔用的 Memory 較少,另外需要注意的一點是,thread 和 fork 是可以結合使用的,結合使用時可分為兩種:一種是 fork 的時候將 parent process 全部複製;另一種是只有複製 parent process 中呼叫 fork() 的 thread。

How to repair and clone disk with ddrescue

  ddrescue  is a tool that can be used to repair and clone disks on a  Linux system . This includes hard drives, partitions, DVD discs, flas...