Events Demonstration - AddHandler

imports System


imports System.Drawing

imports System.Windows.Forms



public class EventsDemo : inherits System.Windows.Forms.Form



Private btn as Button



public sub New()

btn = new Button()

btn.Location = new Point(50,50)

btn.Text = "Test"



Controls.Add(btn)

AddHandler btn.Click, AddressOf btn_Click

end sub



public shared sub Main()

Application.Run(new EventsDemo())

end sub



private sub btn_Click(ByVal sender as object,ByVal e as EventArgs)

MessageBox.Show("btn_Click method","Events Demonstration")

end sub

end class

vb.net中的region區塊在close狀態下無法搜尋內部的字串!?

問題一:




剛剛測試了一下,如果是開啟大綱模式Ctrl+M -> Ctrl+O



此時要展開所有區塊 Ctrl+M -> Ctrl+M,則只會展開到顯示region的title而已



例如:



+ region描述一



+ region 描述二



public Sub Test()



'''''



End Sub







但是如果關閉大綱模式 Ctrl+M -> Ctrl+P



則可以展開所有的區塊



例如:



# region "region描述一"



public sub Test2()



....



End Sub







public sub Test3()



....



End Sub



# End Region







public sub Test()



....



End Sub







問題二:



也剛好找到解答了,只要在Search時候勾選 "Search Hidden Text" ,就可以搜尋到沒有展開的Region內的字串了。

Protected 修飾詞可用於以下內容中

Protected : 指定一或多個已宣告的程式設計項目只可從自己的類別或從衍生類別中進行存取

Class 陳述式
宣告類別的名稱,並引入組成類別的變數、屬性 (Property)、事件和程序的定義


Const 陳述式
宣告並定義一或多個常數

Declare 陳述式
宣告在外部檔案中所實作之程序的參考

Delegate 陳述式
用來宣告委派 (Delegate)。委派是一種參考型別,它參考型別的 Shared 方法或物件的執行個體方法 (Instance Method)。任何具有相符參數型別和傳回型別的程序都可用來建立這個委派類別的執行個體。接著可透過委派執行個體來叫用程序

Dim 陳述式
為一或多個變數宣告和配置儲存空間

Enum 陳述式
宣告列舉型別並定義其成員值

Event 陳述式
宣告使用者定義事件

function 陳述式
宣告用於定義 Function 程序的名稱、參數和程式碼

Interface 陳述式
宣告介面的名稱並引入組成介面之成員的定義

Property 陳述式
宣告屬性 (Property) 的名稱以及用來儲存和擷取屬性值的屬性程序

Structure 陳述式
宣告結構的名稱,並引入組成結構之變數、屬性 (Property)、事件和程序的定義

Sub 陳述式
宣告定義 Sub 程序的名稱、參數和程式碼

property,get,set 语句祥解

property


   get

   End Get

   Set

   End Set

End property
 
property....End property里面设置属性

get...End Get是读取属性值,比如读取textbox.text
set...End set是设置属性值,比如设置textbox.readonly=true



因是因為, 這是兩個不同的Form1類別執行個體.




比方說你把程式改為這樣



Public Class Class1

Public Shared Sub ThreadProcSafe()

Form1.SetText("This text was set safely.")

Form1.ShowDialog()

End Sub

End Class



你就會發現預期的效果其實是出現在另外一個Form1. 而非原本的Form1



如果你要正確的結果, 就必須將原來的Form1執行個體傳遞給這個靜態方法:



ex:



Public Class Form1

Delegate Sub SetTextCallback(ByVal [text] As String)



Public demoThread As Thread = Nothing



Public Sub SetText(ByVal [text] As String)



If Me.TextBox1.InvokeRequired Then

Dim d As New SetTextCallback(AddressOf SetText)

Me.Invoke(d, New Object() {[text]})

Else

Me.TextBox1.Text = [text]

End If

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Class1._mainForm = Me

Me.demoThread = New Thread(New ThreadStart(AddressOf Class1.ThreadProcSafe))

Me.demoThread.Start()

End Sub



End Class



Public Class Class1

Private Shared m_mainForm As Form1



Public Shared Property _mainForm As Form1

Get

Return m_mainForm

End Get

Set(ByVal value As Form1)

m_mainForm = value

End Set

End Property

Public Shared Sub ThreadProcSafe()

_mainForm.SetText("This text was set safely.")

End Sub

End Class

使用 Visual Basic .NET 的多執行緒程式開發

http://www.microsoft.com/taiwan/msdn/library/2002/Apr-2002/whitepaper/vbtchAsyncProcVB.htm

建立新的執行緒

建立執行緒最直接的方法就是建立執行緒類別的一個新執行個體,並且使用 AddressOf 陳述式傳遞您要執行之程序的委派。例如,下列程式碼會將名為 SomeTask 的子程序當成另一個執行緒執行。

Dim Thread1 As New System.Threading.Thread(AddressOf SomeTask)

Thread1.Start

' 此處的程式碼會立即執行。


執行緒共用


執行緒共用是多執行緒的一種形式,工作會加入佇列中,並在建立執行緒時自動啟動。使用執行緒共用時,您要呼叫 Threadpool.QueueUserWorkItem 方法,使用您要執行之程序的委派,Visual Basic .NET 會建立執行緒並執行您的程序。以下範例顯示可以如何使用執行緒共用啟動許多工作。

Sub DoWork()

Dim TPool As System.Threading.ThreadPool

' 佇列工作

TPool.QueueUserWorkItem(New System.Threading.WaitCallback _

(AddressOf SomeLongTask))

' 佇列另一個工作

TPool.QueueUserWorkItem(New System.Threading.WaitCallback _

(AddressOf AnotherLongTask))

End Sub



有一點要釐清的:Join 是一個同步或封鎖呼叫。您呼叫了 Join 或等候處理常式的等候方法後,呼叫程序會停止,等候執行緒通知其已經完成。


Sub JoinThreads()

Dim Thread1 As New System.Threading.Thread(AddressOf SomeTask)

Thread1.Start()

Thread1.Join() ' 等候執行緒完成。

MsgBox("執行緒已經完成")

End Sub

Wince6.0的安装

data from : http://bbs.msembed.com/showtopic-2513.aspx

今天在群里受小安所托,整理一下WINCE6.0的安装过程,后面看了下聊天记录,发现有很多人自今仍为CE6.0的安装困扰,不是安装失败就是无法编译成功,有的甚至出现破坏先前安装的5.0版本的现象,针对这种现象,结合网上的安装文档,我总结了安装指导说明,仅供群里成员使用。


PS:文中所指的安装程序路径为我拿到的软件包及在我PC的路径,请根据您的具体路径来修正。

Window CE6.0安装顺序



Windows CE6.0的安装过程繁琐,为确保安装顺利,请仔细阅读本文,按照步骤一步一步进行安装。

一、所需安装软件包括

1、Visual Studio 2005

2、Visual Studio 2005 Service Pack 1

3、MSDN(可选)

4、Windows Embedded CE6.0(即PB6.0)

5、Windows Embedded CE 6.0 Platform Builder Service Pack 1

6、WINCE6.0R2

7、Microsoft Device Emulator 2.0

8、Virtual Machine Network Driver for Microsoft Device Emulator

9、WINCE6.0 Updates

二、所用磁盘空间

在安装之前,请检查您PC的磁盘空间,目标安装盘剩余空间最好大于15G,建议30个G,因为还要有R3和以后的系统定制和应用开发。C盘剩余空间最好大于4G,建议目标安装盘不要选择C盘。

安装程序

所用磁盘空间

Visual Studio 2005

2G

Visual Studio 2005 Service Pack 1

1.8G (C盘)

MSDN

1.5G

Windows Embedded CE6.0 (ARMV4I、X86)

7.8G (C盘1G)

WINCE6.0R2

几百M

总共:14G左右



三、安装顺序

1、先安装Visual Studio 2005

安装程序位于VS2005\VSTS\vs目录下,直接双击该目录下setup.exe进行安装。最好别用DEFAULT安装,把组件CUSTOM一下,不然会花很多冤枉的磁盘空间。WINCE600的Platform Builder不像WINCE500是独立的,而是作为VS2005的插件,以后建立和定制OS、编译调试全部在VS2005里完成。



2、安装Visual Studio 2005 Service Pack 1

安装程序位于\VS2005\VSTS\sp1目录下,直接双击该目录下VS80sp1-KB926601-X86-ENU.exe进行安装。这是必须的装的,Release Note里面提到SP1提供了Windows Embedded 6.0 platform and tools support。安装文件为VS80sp1-KB926601-X86-ENU.exe。此补丁对不同的VS2005版本(Standard / Professional / Tem Edition) 都适用。

如果您用的是Vista系统,装完此补丁后,还要装VS80sp1-KB932232-X86-ENU.exe补丁。

3、安装MSDN

安装程序位于\VS2005\VSTS\msdn目录下,直接双击该目录下setup.exe进行安装。

4、安装Windows Embedded CE6.0

安装程序位于\CE6\Windows Embedded CE 6.0\目录下,直接双击该目录下setup.exe进行安装。在安装过程中,请注意选择安装路径,在选择CPU类型时,根据您目标硬件平台来选择,考虑节省磁盘空间,建议只选ARMV4I和X86。

这里要特别的注意,如何选择路径的问题,小安就是个例子(不要骂我呦,嘿嘿),安装CE 6.0时,选中要安装的选项后选浏览,就可以更改目录了。这里可以参考GM的安装说明,如下:

http://blog.csdn.net/gooogleman/archive/2009/05/28/4219567.aspx

5、安装Windows Embedded CE 6.0 Platform Builder Service Pack 1

安装程序位于\CE6\Windows Embedded CE 6.0 Platform Builder Service Pack 1\目录下,直接双击该目录下Windows Embedded CE 6.0 Platform Builder Service Pack 1.msi进行安装。



6、安装WINCE6.0R2

安装程序位于\CE6\CE6R2\目录下,直接双击该目录下setup.exe进行安装。

这里要对WINCE6.0R2进行必要的说明,WinCE6.0 R2 是WinCE6.0的一个增强组件,相当于WinCE6.0的补丁,先安装WinCE6.0之后再安装WinCE6.0 R2就OK!



7、安装Microsoft Device Emulator 2.0

安装程序位于\CE6\Microsoft Device Emulator 2.0\目录下,直接双击该目录下vs_emulator20.exe进行安装。



8、安装Virtual Machine Network Driver for Microsoft Device Emulator

安装程序位于\CE6\ Virtual Machine Network Driver for Microsoft Device Emulator\目录下,直接双击该目录下Virtual Machine Network Driver for Microsoft Device Emulator.msi进行安装。



9、安装WINCE6.0 Updates

安装程序位于\CE6\WinCe 6.0 Patches\目录下,请仔细查看文件的时间序,安装时间序一个一个安装,从WinCEPB60-061231-Product-Update-Rollup-Armv4I.msi开始装,这里只提供到EPB60-080731-2008M07-Armv4I.msi。欲升级最新补丁,请登录微软网站下载http://www.microsoft.com/windows ... etting-started.mspx

10. 安装WINCE 6.0 R3

利用最新发布的 Windows Embedded CE 6.0 R3,设备制造商可以使用熟悉的工具和创新的技术,创建用户界面更具沉浸感、浏览体验更丰富多彩、与 Windows PC、服务器、服务和设备的连接更具特色的与众不同的设备。以高性能、高可靠性 Windows Embedded CE 平台为基础,设备制造商可以快速、高效地将其设备推向市场。具体怎么样,我也不清楚,我只是把它安装了,怎么用,以后和大家一起探讨吧。

下载地址:http://www.cevx.com/bbs/viewthre ... %26amp%3Btypeid%3D5

当然,有个大家熟悉的牛人做了个调试助手,我把链接发过来:

需要的同学请到这里下载:

http://files.cnblogs.com/we-hjb/R3DownLoad.rar

Viewers for Windows Embedded CE 6.0 R3

Mobile QQ Messenger Client for Windows Embedded CE 6.0 R3

至此,Windows CE6.0 所有软件安装完毕。

下面我将各个部分的网址链接在这里给出,大家按照上面的步骤,从下面的链接下载即可,不敢保证所有的网址都能正常打开,如果有什么不能下载的,请和我联系,我尽快做出修改。



下载地址:

本文以WINCE6.0 180天免费试用版说明如何安装WINCE6.0 R2

注意必须有足够的硬盘空间。

1. 安装Visual Studio 2005

WINCE6.0作为Visual studio 2005的一个插件,必须首先安装VS2005。

2. 安装VS2005 SP1补丁

根据安装的VS2005的语言版本下载并安装相应的SP1补丁,比如

中文版SP1补丁下载地址:

http://www.microsoft.com/downloa ... 6-b39d-37baf6b5b1dc



英文版SP1补丁下载地址:

http://www.microsoft.com/downloa ... 6-b39d-37baf6b5b1dc

『说明』请注意,完整安装过程需要耗费较长时间。

3. 安装WINCE6.0

如果使用WINCE6.0 180天试用版可以到

http://www.microsoft.com/windowsembedded/eval/trial.mspx



注册一个密匙并在线安装WINCE6.0,安装速度视网速而定,如果网速不好,可以到网上找离线安装包下载。

安装时注意在选择bsp时选上ARMV4l。

4. 安装WINCE6.0 SP1补丁

下载并安装Windows Embedded CE 6.0 Platform Builder Service Pack 1.msi,下载地址:

http://www.microsoft.com/downloa ... &displaylang=en

5. 安装WINCE6.0 R2

在线安装WINCE6.0 R2,地址:

http://www.microsoft.com/downloa ... &DisplayLang=en



也可以从网上找离线安装包下载后安装。

6. 给WINCE6.0打补丁

按照时间顺序打补丁,补丁从2007年年底开始。

注意6410必须打上08年1月的补丁WinCEPB60-080131-2008M01-Armv4I.msi,否则会编译失败,下载地址:

http://www.microsoft.com/downloa ... &DisplayLang=en

7. 升级.NET Cmpact Framwork3.5

下载地址:

http://www.microsoft.com/downloa ... &DisplayLang=en



8.VS2005:

最后,我要补充一点,在安装完Visual Studio 2005之后,应该首先安装VS 2005 SP1,然后再安装PB 6.0。毕竟PB是作为一个插件出现在VS 2005中的,接下来还需要安装PB 6.0 SP1,可以在微软网站上下载,下载地址为:www.microsoft.com/downloads/deta ... &displaylang=en



补充:

wince6.0的安装顺序&VS2005(下)Platform Buidler for CE 6.0离线安装包下载:

http://hi.baidu.com/tommy1987090 ... 71073333fa1cd0.html

本文参考网址:

http://hi.baidu.com/ch_ff/blog/item/7488ee9578638b19d31b7006.html

http://blog.mcuol.com/User/lqshu/Article/15812_1.htm

http://hi.baidu.com/jjzhang166/b ... 134a4ff21fe786.html

http://blog.csdn.net/gooogleman/archive/2009/05/28/4219567.aspx

http://blog.163.com/mfk_happy/bl ... 942008816102254414/

http://www.esdevelop.cn/category/windowsce/200801/wince_6.html

http://www.cnblogs.com/we-hjb/archive/2009/10/14/1583500.html

多线程编程中Join与WaitOne的区别

Join:
在一个线程MainThread中开启一个新的线程NewThread,在完成初始化并启动NewThread的操作后,调用Join,则MainThread堵塞,直到NewThread执行完毕,MainThread才继续执行。




WaitOne:
在一个线程MainThread中开启一个新的线程NewThread,在完成初始化并启动NewThread的操作后,调用WaitOne,则MainThread堵塞,直到在NewThread中调用Set,MainThread才继续执行。

不錯的各式VB教學網站

http://www.java2s.com/

NP hw1 參考程式範例

Dear all


我是 NP 培訓班課程的 TA

禮拜四的練習作業參考程式已經釋出

path在mcbsd工作站的/tmp/hw1, 請執行 %cp -r /tmp/hw1 ~/. 到自己家目錄下

這裡簡單地解釋程式的用法:

1. 由於加密後, 有可能出現不能夠print out的字元 (會造成解密後結果與原本不符), 因此client端會把server回傳的結果存在一個二維陣列中

2. client 端可執行/list指令, 秀出目前儲存加密訊息的內容, 並以index指向每個不同的entry

3. 未來client只要執行 /decrypt en_ch index (en_ch是解密字元、index是加密訊息的所在index)

4. 加密可能造成NULL char的出現, ex: /encrypt a aaaa, 參考程式中已經濾掉這個情況

以上是因為TA在設計作業時, 沒有詳加考慮的地方.

我在程式中加入適當的comment, 希望這份程式對大家認識網路程式有所幫助

若要編譯, 可以透過Makefile, 執行 %make clean all , 即可清掉object檔和執行檔, 重新編譯出新的檔案

有問題請回信給TA, 或是於上課時提問
BRs
mcchung

寫作程式時,需注意以下風格

  • 程式開頭應加註解,說明用途,建立時間,修改時間與內容,作者,使用工具


  • 函數的開頭也應對此函數註解說明

  • 見到{應內縮四個空格,以讓程式容易閱讀

  • 每一敘述應獨立一行,也就是說看到;{應該換行

Software development process

撰寫程式的流程如下圖,所需要的工具包括Text Editor,Preprocessor,Compiler,Linker等四種

Text Editor:程式設計師利用此工具編輯(Edit)Source code file(Text Format), 也就是說產生.c檔的工具。



Preprocessor:結合Source code file(.c檔)和零到多個Header files(.h檔),經過編輯(Edit)後成為另一個修改過的Source code file。

Compiler:將source code編譯(compile)產生Object code file(.o檔, Binary Format),同一個作業平台的Object code格式相同,也就是說Object code file可以由不同程式語言的Compiler產生。


Linker:將幾個Object code files連結(link)產生一個可執行檔(.exe檔)。


如果你的開發環境是在Windows上,下面有關vi和gcc的說明可以跳過。

在Unix作業系統內,最常見的Text Editor是vi。
  Preprocessor,Compiler和Linker可以是三個不同的程式,也可以包成一個。Unix作業系統上最常見的C語言開發環境是gcc(GNU C Compiler),他把Preprocessor,Compiler和Linker三個功能合在一起以方便使用。最簡便的用法是:

gcc hello.c

  若hello.c完全沒有錯誤,則以上命令會產生一個執行檔a.out,在命令列下打a.out即可觀察你所寫程式的執行結果。有時候若你設定的環境變數不對,則可能出現Command Not Found的錯誤,此時你可輸入./a.out。若不想讓gcc編譯出來的執行檔叫做a.out,則可下達以下命令:

gcc -o exename hello.c

  撰寫大型程式時,很可能會有多個.c的原始程式檔,假設他們的名稱是source1.c, source2.c, source3.c...如果要個別編譯這些source code,則下達如下命令:
gcc -c source1.c

  若編譯成功,會產生source1.o的檔案。要將數個Object Code連結成為一個可執行檔,則下達以下命令:
gcc source1.o source2.o source3.o

  至於Windows作業系統上的程式編寫環境,最常使用的是Microsoft Visual Studio,裡面就包含了Visual C++的開發環境。因為C++可視為C語言的父集合,因此你也可以用Visual C++來開發C程式。這類視覺化的開發工具(Dev C++也是其中一種),已經把Text Editor, Preprocessor, Compiler, Linker整合在一起, 並包括Project Management(專案管理)等功能, 因此這類工具又稱為Integrated Development Environment(IDE,整合開發環境)。

電腦概論重要名詞

Control Unit(控制單元): 負責指令的擷取和解釋


ALU(Arithmetic and Logic Unit, 算數與邏輯單元): 負責算數與邏輯指令的實際執行工作,裡面有一些記憶體供計算所需,特別稱為Register(暫存器)。暫存器的數量隨硬體而不同,此處說明用的虛擬電腦只有一個暫存器。 一般常見的暫存器則有

累加器(Accumulator):儲存執行運算的資料

旗標暫存器(Flag Register):儲存運算處理後的CPU狀態

程式計數器(Program Counter):儲存目前執行指令所在的地址

基底暫存器(Base Register):表達某塊記憶體空間的開始位置

索引暫存器(Index Register):儲存基底暫存器的相對位置

通用暫存器(General Purpose Register):儲存一般資料

指令暫存器(Instruction Register):儲存指令。僅供CPU內部使用
 
 
在上圖的機器中共有100個記憶體可用,每個記憶體可以存放3個數字。Control Unit, ALU, Program Counter在現代的硬體設計裡多做在一起,稱為CPU(Central Processing Unit)。Pentium 4就是Intel這家公司的CPU產品。
電腦執行一個機器指令的步驟為:
1.Fetch(擷取指令): 由Control Unit讀取Program Counter的內容,根據Program 2.Counter的數值去相對應的Memory抓指令
3.Decode(解碼): 抓到的指令經Control Unit判讀,決定要如何執行該指令
4.Execute(執行): 在ALU(Alrithmetic and Logic Unit)裡執行該指令
5.Write(寫回): 更改Program Counter的內容

電腦系統概論

資料來源:http://programming.im.ncnu.edu.tw/C_index.html

程式寫作概論 http://programming.im.ncnu.edu.tw/Chapter0.htm
電腦系統概論 http://programming.im.ncnu.edu.tw/Chapter1.htm
電腦內部運作 http://programming.im.ncnu.edu.tw/Chapter2.htm
C語言的總覽 http://programming.im.ncnu.edu.tw/Chapter3.htm
C的工具語言 http://programming.im.ncnu.edu.tw/Chapter4.htm
型別與運算 http://programming.im.ncnu.edu.tw/Chapter5.htm
流程控制 http://programming.im.ncnu.edu.tw/Chapter6.htm
迴圈範例練習 http://programming.im.ncnu.edu.tw/Chapter7.htm
函數與遞迴http://programming.im.ncnu.edu.tw/Chapter8.htm
指標 http://programming.im.ncnu.edu.tw/Chapter9.htm
陣列 http://programming.im.ncnu.edu.tw/Chapter10.htm
字元字串 http://programming.im.ncnu.edu.tw/Chapter11.htm
指標陣列函數 http://programming.im.ncnu.edu.tw/Chapter12.htm
結構 http://programming.im.ncnu.edu.tw/Chapter13.htm
基本資料結構 http://programming.im.ncnu.edu.tw/Chapter14.htm
範例練習 http://programming.im.ncnu.edu.tw/Chapter15.htm

如何計算CRC值?

CRC-check 算法如下:


1. 令16-bits暫存器 CRC=FFFF (Hex)。

2. 第一個8-bit byte值與CRC暫存器做 Xor,將結果存入CRC暫存器內。

3. CRC暫存器右移一位 bit,然後將 0 填入至高位元。

4. 檢查右移的值如果是 0,則將新值放入CRC暫存器內,否則將新值與A001(Hex)做 Xor,

  將其結果存入CRC暫存器內。

5. 重複步驟 3~4,直到 8個 bit 全部運算完成。

6. 重複步驟 2~5,取下一個 8-bit 訊息資料做運算,直到所有訊息資料運算完成,即是CRC的檢查碼。

嵌入式系統專案實務 fork 及vfork的差異

fork()和vfork()這兩個系統功能都可以複製出和呼叫者﹙parent﹚完全相同的process﹙child﹚,但呼叫vfork()後的parent process會被暫停,直到被複製出來的child process執行了exec()或exit();而呼叫fork()後的parent process會和新產生的child process平行﹙concurrent﹚執行。

接下來我們必須約略解釋一下fork()在Linux中的實現方式,旨在讓讀者知道為什麼這個系統功能沒法直接移植到沒有MMU的CPU上;首先我們必須先介紹一下”copy-on-write”這個觀念:
一個程式在執行時會佔據記憶體空間,粗略可分為程式段、資料段、堆疊段與常數段,其中程式段與堆疊段是唯讀的,資料段與堆疊段的內容則有可能在執行時期被改變。在Linux中,當某個process呼叫fork()產生child process時,系統只會為新的process配置堆疊段,其他的記憶體區段都是共用的;實際上在child process呼叫exec()去執行另一個程式前,諸如程式段以及常數段這些內容不可以被改變的記憶體區段始終可以共用。可是資料段就不能一直共用,如果parent與child process同時去操作某個變數勢必會引起混亂。

Child process被fork出來後馬上呼叫exec()去執行其他程式是最常用的流程,以此說來,雖然每個process都必須有獨立的資料段,但馬上為child process配置資料段是很不經濟的,因為在大部分的狀況下child process並不會去對資料段作寫入的動作,在執行exec()後,之前的資料段就沒用了。

為了解決這個問題,Linux(fork)採用”copy-on-write”的技術,在child process尚未對資料段作寫入的動作之前,parent與child process共用資料段;當child process對資料段記憶體作出寫入的要求時,系統會配置一塊實體記憶體﹙一個page﹚給child process,並將原本資料段中被要求寫入之page的內容複製到這塊新的page;接著系統會更改child process的page table,使要被寫入資料的虛擬位址可以對應到上述新配置的實體記憶體位址。

此時child process與parent process的資料段大部分都還是功用的,不同的地方只是這次要被寫入的page;這種演算法的好處很多,在最節省記憶體的前提下使得parent與child process不致互相影響。要達到這種效果,CPU沒有支援MMU是做不到的,所以uClinux無法直接支援fork()這個系統功能。
uClinux無法作到安全的資料段分享機制,產生child process後複製整塊資料段也顯得有點笨拙,於是只好讓parent process停止執行,直到child process結束執行或有了自己的資料段之後才能恢復執行,前者表示child process出現例外或呼叫了_exit(),而後者則表示child process呼叫了exec()去執行其他的程式。這樣妥協出來的功能,就是原本Linux中的vfork()系統呼叫。

如果讀者對copy-on-write的原理不清楚也沒關係,讀者在使用uClinux時只需知道一般Linux在實現fork()這個系統功能時必須用到MMU的機制,而uClinux執行在沒有MMU的CPU之上,所以fork()無法直接移植到uClinux上;uClinux提供vfork()以達到多工的效果。

必須注意的是,使用vfork()產生的child process很可能會破壞parent process原本的資料段,所以程式設計師在uClinux上使用vfork()時必須格外小心;而且沒有fork()系統功能的事實使得許多原本運行在Linux上的應用程式無法完全不經修改救執行於uClinux之上。

我的心得:在早期的fork會複製整個parent的address space,造成時間的浪費,使用vfork則不會複製parent的address space。近來的fork則使用copy-on-write的技術,但是這卻需要MMU的幫忙,才能將child process的page table修改成正確的physcial address,而在嵌入式系統上,uClinux並不支援MMU,所以只能使用vfork。

memcpy 跟strcpy 用法上的差別

strcpy()只能透過零結尾來判定結束,所以有以下的缺點:


1. 速度慢,因為只能以BYTE為單位執行拷貝。

2. 容易出現overlay/memory-corruption,這有兩個情況,一個是目標緩衝區太小了,另一個是來源忘了零結尾。

3. 重疊的情況時,拷貝會出錯。

memcpy()透過第三個參數來得知拷貝的長度,程式本身可以優化,也就是速度可以快些,再加上拷貝的長度由程式師指定,比較不容易出錯,但重疊的情況仍有問題,這種情形需須改成呼叫memmove()。