多執行緒伺服器是對多程序伺服器的改進,由於多程序伺服器在建立程序時要消耗較大的系統資源,所以用執行緒來取代程序,這樣服務處理程式可以較快的建立。據統計,建立執行緒與建立程序要快 10100 倍,所以又把執行緒稱為「輕量級」程序。執行緒與程序不同的是:乙個程序內的所有執行緒共享相同的全域性記憶體、全域性變數等資訊,這種機制又帶來了同步問題。例如,在accept的時候,由於兩個客戶端相連太近了,導致上乙個程序還沒有把字串處理完畢,下乙個程序又開始覆蓋字串,這裡就會出問題,因此必須用鎖,就算下乙個程序來了,到了那裡,也只能被鎖攔下。
因為執行緒可以共用全域性變數,在accept之前上鎖,在接收資料前(recv)解鎖。就是可以讓client_sock可以傳位址。如果不傳位址的話,其實並沒有什麼共用的部分。畢竟,函式傳參部分很有可能是個結構體呢。
可以想象,sock不關閉,通話就一直接通。
accept函式的作用並不像每次抓取乙個資料報,更像是兩個開著的手機建立乙個連線。因為在迴圈裡,所以它要不就在這裡阻塞,要不就執行乙個while迴圈體。而recv也是乙個阻塞函式,但它就像收資訊一樣了。
因為是一對多的關係,不僅客戶端有權關閉自己的sock,伺服器端也有權關閉客戶端的sock。
而recv函式,才像是獲取資料報的過程,等recv返回-1,證明client自己先關閉了sock,然後伺服器才能關閉客戶端的sock,同樣的,服務端也有權提前關閉客戶端的sock,這就說得通了。
現在說並髮式連線的一般規律:
多程序:簡單,但資源消耗極大,一般不超過10個用,因此只適合做demo,不具有實際價值。
多執行緒:複雜一點點,需要考慮執行緒同步,另外也是不能啟用太多執行緒。
每日小常識:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
pthread_t *thread: 傳遞乙個pthread_t變數位址進來,用於儲存新執行緒的tid(執行緒id)
const pthread_attr_t *attr: 執行緒屬性設定,如使用預設屬性,則傳null
void *(*start_routine) (void *): 函式指標,指向新執行緒應該載入執行的函式模組
void *arg: 指定執行緒將要載入呼叫的那個函式的引數
返回值:成功返回0,失敗返回錯誤號。以前學過的系統函式都是成功返回0,失敗返回-1,而錯誤號儲存在全域性變數errno中,而pthread庫的函式都是通過返回值返回錯誤號,雖然每個執行緒也都有乙個errno,但這是為了相容其它函式介面而提供的,pthread庫本身並不使用它,通過返回值返回錯誤碼更加清晰。
在linux中,64位的指標就是8個位元組。不像windows裡一樣。
Linux核心學習筆記六 併發和同步概念
一 臨界區和競爭條件 臨界區 訪問和操作共享資料的 段。競爭條件 多個執行執行緒處於同乙個臨界區中。處於競爭條件 造成訪問的資料或者資源不一致狀態 對資源i的訪問 processa和b訪問後得到正確的結果應該是9 程序是併發執行,有可能得到的結果是 8 防止這種情況的發生 保證對資源的訪問原子操作。...
Linux核心併發機制 原子操作
很多人會問這樣的問題,linux核心中提供了各式各樣的鎖機制到底有何作用?追根到底其實是由於作業系統中存在多程序對共享資源的併發訪問,從而引起了程序間的競態。這其中包括了我們所熟知的smp系統,多核間的相互競爭資源,單cpu之間的相互競爭,中斷和程序間的相互搶占等諸多問題。所謂的原子操作,就是該操作...
LINUX核心引數,針對TCP協議優化
程序可以同時開啟的最大控制代碼數,限制最大併發連線數 fs.file max 999999 允許time wait狀態的socket重新用於新的tcp連線 net.ipv4.tcp tw reuse 1 當keepalive啟用時,tcp傳送keepalive訊息的頻度,預設是2個小時。設定小些,可...