FileZilla FTP服務(wù)器源代碼分析(5)
FileZilla FTP服務(wù)器源代碼分析:FileZilla是一款免費而且開源的FTP工具。包括FileZilla Client,F(xiàn)ileZilla Server兩個版本。FileZilla Server只提供了windows系統(tǒng)下的版本,我們要將本地的網(wǎng)站網(wǎng)頁文件上傳到網(wǎng)站服務(wù)器,或從服務(wù)器下載網(wǎng)頁文件,只需FileZilla Client客戶端版本就可以了。FileZilla FTP服務(wù)器源代碼分析
win32同步控制機制(Synchronization)
1、Critical Sections(關(guān)鍵域)
最簡單的一種同步機制,創(chuàng)建和銷毀的函數(shù)是:
- InitializeCriticalSection()
- DeleteCriticalSection()
在被創(chuàng)建后,使用如下函數(shù)實現(xiàn)線程同步,
- EnterCritSection()
... 需要同步的代碼
- LeaveCritSection()
即在同一時間內(nèi),EnterCritSection和LeaveCritSection中間的代碼只能被一個線程處理。注意的問題是:
Critical Sections類型的變量并不是一個核心對象,即沒有handle;
它存在于進程的內(nèi)存空間中,即不可跨進程使用;
可能會導致死鎖;
2、Mutexes(互斥器)
創(chuàng)建和銷毀的函數(shù)是:
- CreateMutex()
- CloseHandle()
如果Mutex已經(jīng)被創(chuàng)建,這樣打開和關(guān)閉:
- OpenMutex()
- ReleaseMutex()
使用的時候,用wait函數(shù)來等待Mutex,一旦沒有線程擁有這個Mutex,這個線程就會獲得這個Mutex,在這個線程處理完以后,調(diào)用ReleaseMutex()可以釋放這個Mutex,其它等待中的線程就會重新競爭這個Mutex,同時只能有一個線程獲得這個Mutex,沒競爭到的線程則處于blocking阻塞狀態(tài)。常見的wait函數(shù)有:
WaitForSingleObject() // 等待一個mutex
WaitForMultipleObjects() // 同時等待多個mutex,要不同時擁有多個,要不一個也沒有
和Critical Sections相比,mutex是一個核心對象,因此是跨進程的,即多個進程可以使用同一個mutex,并且CreateMutex()的開銷比InitializeCriticalSection()要大得多。
相比而言,mutex更重量級,更慢,但也更靈活。
3、信號量(Semaphores)
創(chuàng)建和銷毀的函數(shù)是:
CreateSemaphore()
CloseHandle()
獲取這個Semaphore的函數(shù)同樣是那些wait函數(shù)WaitForSingleObject(), WaitForMultipleObjects()等等。
使用Semaphores的含義是:Semaphores可以同時被多個線程擁有,但在CreateSemaphore()時會指定一個同時擁有這個Semaphore的最大線程數(shù),即每個線程調(diào)用wait函數(shù)獲取Semaphore時,Semaphore內(nèi)部的可用值就會減1,一旦可用值為0,則線程必須等待。當擁到Semaphore的線程運行完后,也應(yīng)該調(diào)用ReleaseSemaphore()來釋放。
同Mutexes不一樣的是,調(diào)用ReleaseSemaphore()的線程并一定是調(diào)用wait并獲得擁有權(quán)的那個線程,即任何線程都可以在任何時間調(diào)用ReleaseSemaphore()來解除被任何線程鎖定的Semaphore。
在某種意義上,Mutexes可以看成是Semaphore的一個特例,即只能同時被一個線程鎖定的Semaphore。
Semaphore也是核心對象。
4、事件(Event Objects)
win32中最靈活的應(yīng)該是events了,它也是一種核心對象。
events的含義在于:events有兩種狀態(tài),激活和非激活,在events被激活時,那些等待著的線程會被喚醒。
創(chuàng)建和銷毀的函數(shù)是:
CreateEvent(),創(chuàng)建時可以指定events是manual或automatic,manual的含義是events的狀態(tài)是由程序員設(shè)定的。automatic的含義是events變成激話后,立即自動變成非激活。
CloseHandle()
獲取這個events的函數(shù)同樣是那些wait函數(shù)WaitForSingleObject(), WaitForMultipleObjects()等等。
下面三個方法可以改變events的狀態(tài):
SetEvent(): 把events設(shè)為激活
ResetEvent(): 把events設(shè)為非激活
PulseEvent(): 激活events,然后立即高為非激活。如果events是manual的,則喚醒所有等待的線程,如果events是automatic的,同喚醒“一個”等待的線程。
注意,如果event是manual時,這時調(diào)用SetEvent后,如果不調(diào)用ResetEvent,則等待中的線程會被不斷的喚醒,即不斷地執(zhí)行CreateThread時指定的lpStartAddress方法。
還有一點,windows系統(tǒng)可以保證被喚醒的線程是一個接著一個的,即不會有的線程總是被喚醒,而有些線程被餓死。
【編輯推薦】