Linux環(huán)境編程對于初學者來說,必須深刻理解重點概念才能更好地編寫代碼,實現(xiàn)業(yè)務功能,下面就幾個重要的及常用的知識點進行說明。搞懂這幾個概念后以免在將來的編碼出現(xiàn)混淆。
系統(tǒng)調用
所有的操作系統(tǒng)在其內核里都有一些內建的函數(shù),這些函數(shù)可以用來完成一些系統(tǒng)級別的功能。在Linux系統(tǒng)使用的這樣的函數(shù)叫做“系統(tǒng)調用”,英文是systemcall。這些函數(shù)代表了從用戶空間到內核空間的一種轉換。
系統(tǒng)調用是Linux操作系統(tǒng)提供的服務,是編寫應用程序與內核之間通信的接口,也就是我們所說的函數(shù)。相對于普通的函數(shù)調用來說,系統(tǒng)調用的性能消耗相對來說是大的。所以在程序追求性能的同時,盡量避免系統(tǒng)調用。
用戶態(tài)的程序默認是通過棧來傳遞參數(shù)的。而對于系統(tǒng)調用來說,內核態(tài)和用戶態(tài)使用的是不同的棧,這使得系統(tǒng)調用的參數(shù)只能通過寄存器的方式進行傳遞。
IO操作
什么是IO,通俗來講就是輸入輸出
IO分為標準IO和文件IO,我們常用的scanf、printf、getchar、putchar、gets、puts這些都是標準輸入輸出。Linux系統(tǒng)下一切皆文件的概念,所以在linux下的編程中對文件的IO操作有標準IO和文件IO兩種操作類型。標準IO是帶緩沖的IO屬于庫函數(shù),文件IO是不帶緩沖的屬于系統(tǒng)調用。
標準IO:
1.標準IO是由ANSIC標準定義 2.跨平臺,可以在windows下運行,也可以在Linux下運行 3.通過緩沖機制來減少系統(tǒng)調用,實現(xiàn)更高的效率 4.文件流 標準IO用結構體類型來存放文件的相關信息,標準IO所有操作圍繞著FILE來操作。
文件IO:
1.文件IO是POSIX提供的一組函數(shù) 2.只能運行在可移植操作系統(tǒng)中,不能跨平臺 3.沒有緩沖機制 4.文件描述符是一個非負整數(shù),每打開一個文件,系統(tǒng)會自動分配一個文件描述符(即從系統(tǒng)最小的且沒有被用的描述符來分配)
原子操作
原子在化學課程中是不可再分的顆粒。而對于Linux系統(tǒng)來說所謂原子操作是為了確保對一個整型數(shù)據(jù)的更改具有排他性。原子操作就是要么不執(zhí)行,一旦執(zhí)行就會執(zhí)行完成,是不可被打斷的一個,或一系列的動作,即在完成任務前不會被其他事件所打斷,就像原子不可被分割成顆粒一樣。單處理中,可以用單條指令完成的指令可以被看成是一個原子操作。軟件中的原子操作依賴于硬件原子操作的支持。當然原子操作,也可以當引用計數(shù)使用。
原子操作其實本質上和鎖實現(xiàn)同樣的功能,都是為了保護共享對象,它具有原子性,和順序性。原子性確保指令執(zhí)行期間不被打斷,要么全部執(zhí)行,要么根本不執(zhí)行。而順序性確保即使兩條或多條指令出現(xiàn)在獨立的執(zhí)行線程中,甚至獨立的處理器上,它們本該執(zhí)行的順序依然要保持。
線程安全
所謂線程安全,就是指代碼可以在多線程環(huán)境下安全地執(zhí)行,輸出我們想要的結果。即符合正確的邏輯,是程序員期望的正常執(zhí)行結果。為了實現(xiàn)線程安全,Linux系統(tǒng)提供一些列的方法,或者只能使用局部變量或資源,或者就是利用鎖等同步機制,來實現(xiàn)全局變量或資源的訪問。
線程安全在Linux環(huán)境編程中極其重要,我們不僅要了解概念,更重要的是要在實際的編程中學會實現(xiàn)線程安全方式。下面來看一個簡單的例子:
#include#include #include staticintnCnt=0; void*Thread(void*arg) { for(inti=0;i10000;?++i)? ????{ ????????++nCnt; ????} ????return?NULL; } int?main() { ????pthread_t?t1; ????pthread_t?t2; ????/*?創(chuàng)建兩個線程?*/ ????pthread_create(&t1,?NULL,?thread,?NULL); ????pthread_create(&t2,?NULL,?thread,?NULL); ????pthread_join(t1,?NULL); ????pthread_join(t2,?NULL); ????printf("nCnt?is?%d?by?threads ",?nCnt); ????return?0; }
大家看出上面例子的問題了嗎?
對,沒錯,在此例子中我們創(chuàng)建了兩個線程,線程函數(shù)是同一個函數(shù),在線程函數(shù)中是對全局變量nCnt的自增操作。這個例子中輸出結果和我們想要的是不一樣,就是因為nCnt執(zhí)行指令并不是原子的,兩個個線程對nCnt的并發(fā)訪問出現(xiàn)了問題。我們利用鎖就可以解決此問題。
阻塞與非阻塞
Linux環(huán)境編程中的阻塞與非阻塞,都是指I/O操作。而所有的I/O系統(tǒng)調用默認都是阻塞的。那什么是阻塞?阻塞的系統(tǒng)調用是指當進行系統(tǒng)調用時除非出錯或被信號打斷,那么系統(tǒng)調用將會一直陷入內核態(tài)直到調用完成。非阻塞的系統(tǒng)調用是指無論I/O操作成功與否,調用都會立刻返回。阻塞和非阻塞IO是訪問設備的兩種模式,驅動程序可以靈活的支持這兩種用戶空間對設備的訪問方式。
阻塞操作是指在執(zhí)行操作時,若不能獲得資源,則阻塞進程直到滿足條件再進行操作。被阻塞的進程進入睡眠狀態(tài),被調度器的運行隊列移走,直到等待的條件滿足
非阻塞是指在進行操作時,若不能獲得資源,他要么放棄,要么返回后重新查詢,直到可以進行操作為止。
當數(shù)據(jù)準備好時二者的模式相同,即IO操作都是將進程阻塞,直到IO操作完成
阻塞、非阻塞是設備文件、網絡文件的屬性
同步與異步
同步與異步,也是指I/O操作。POSIX定義如下:A synchronous I/O operation causes the requesting process to beblocked until that I/O operation completes An asynchronous I/O operation does not cause the requesting processto be blocked
兩者的區(qū)別就在于同步IO做IO操作時會將進程阻塞,而異步IO做IO操作時不會阻塞進程
當把阻塞、非阻塞、同步和異步放在一起時,難免會出現(xiàn)混淆。同步是否就是阻塞,異步是否就是非阻塞?實際上在I/O操作中,它們是不同的概念。同步既可以是阻塞的,也可以是非阻塞的,而常用的Linux的I/O調用實際上都是同步的。這里的同步和異步,是指I/O數(shù)據(jù)的復制工作是否同步執(zhí)行。
以系統(tǒng)調用read為例。阻塞的read會一直陷入內核態(tài)直到read返回;而非阻塞的read在數(shù)據(jù)未準備就緒時,會直接返回,而當有數(shù)據(jù)時,非阻塞的read同樣會一直陷入內核態(tài),直到read完成。這個read就是同步的操作, 即I/O的完成是在當前執(zhí)行流程下同步完成的。如果是異步,則I/O操作不是隨系統(tǒng)調用同步完成的。調用返回后,I/O操作并沒有完成,而是由操作系統(tǒng)或者某個線程負責真正的I/O操作,等完成后通知原來的線程
審核編輯:湯梓紅
-
接口
+關注
關注
33文章
8775瀏覽量
152394 -
Linux
+關注
關注
87文章
11373瀏覽量
211286 -
操作系統(tǒng)
+關注
關注
37文章
6941瀏覽量
124150 -
編程
+關注
關注
88文章
3649瀏覽量
94343 -
函數(shù)
+關注
關注
3文章
4353瀏覽量
63290
原文標題:Linux環(huán)境編程必須搞懂的幾個概念
文章出處:【微信號:良許Linux,微信公眾號:良許Linux】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
分析EMC問題必須掌握的幾個基本概念
C語言編程入門(linux環(huán)境)
Linux平臺搭建與環(huán)境熟悉
從哪幾個方面入手去學習linux嵌入式編程開發(fā)呢
LINUX環(huán)境編程指南資料合集
linux下c語言編程pdf
LINUX系統(tǒng)教程之如何在Linux系統(tǒng)下進行編程
LINUX環(huán)境編程圖文指南的PDF電子書免費下載

評論