Linux應用編程基礎學習_第1頁
Linux應用編程基礎學習_第2頁
Linux應用編程基礎學習_第3頁
Linux應用編程基礎學習_第4頁
Linux應用編程基礎學習_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

-.z.Linu*下開發(fā)根底知識touch命令:可用于新建文件,如;touch/tmp/zhang*ian.t*t關于volatile的介紹(類型修飾符,指令關鍵字)1.編譯器優(yōu)化介紹由于存訪問速度遠不及CPU處理速度,為提高機器整體性能,在硬件上引入硬件高速緩存Cache,加速對存的訪問。另外在現代CPU中指令的執(zhí)行并不一定嚴格按照順序執(zhí)行,沒有相關性的指令可以亂序執(zhí)行,以充分利用CPU的指令流水線,提高執(zhí)行速度。以上是硬件級別的優(yōu)化。再看軟件一級的優(yōu)化:一種是在編寫代碼時由程序員優(yōu)化,另一種是由編譯器進展優(yōu)化。編譯器優(yōu)化常用的方法有:將存變量緩存到存放器;調整指令順序充分利用CPU指令流水線,常見的是重新排序讀寫指令。對常規(guī)存進展優(yōu)化的時候,這些優(yōu)化是透明的,而且效率很好。由編譯器優(yōu)化或者硬件重新排序引起的問題的解決方法是在從硬件〔或者其他處理器〕的角度看必須以特定順序執(zhí)行的操作之間設置存屏障〔memorybarrier〕,linu*提供了一個宏解決編譯器的執(zhí)行順序問題。2.voidBarrier(void)這個函數通知編譯器插入一個存屏障,但對硬件無效,編譯后的代碼會把當前CPU存放器中的所有修改正的數值存入存,需要這些數據的時候再重新從存中讀出。3.volatile總是與優(yōu)化有關,編譯器有一種技術叫做數據流分析,分析程序中的變量在哪里賦值、在哪里使用、在哪里失效,分析結果可以用于常量合并,常量傳播等優(yōu)化,進一步可以消除一些代碼。但有時這些優(yōu)化不是程序所需要的,這時可以用volatile關鍵字制止做這些優(yōu)化。gccandg++分別是GNU的c&c++編譯器。gcc/g++在執(zhí)行編譯的時候一般有下面4步:⒈預處理,生成.i的文件[預處理器cpp];⒉將預處理后的文件轉換成匯編語言,生成文件.s[編譯器egcs];⒊由匯編變?yōu)槟繕舜a〔機器代碼〕生成.o的文件[匯編器as];⒋連接目標代碼,生成可執(zhí)行程序[器ld];gcc編譯流程分為4個步驟,分別為:預處理〔Pre-Processing〕編譯〔piling〕匯編〔Assembling〕〔Linking〕g++-o-c-g功能-o:指定生成可執(zhí)行文件的名稱。使用方法為:g++-oafilefile.cppfile.h...〔可執(zhí)行文件不可與待編譯或文件同名,否則會生成相應可執(zhí)行文件且覆蓋原編譯或文件〕,如果不使用-o選項,則會生成默認可執(zhí)行文件a.out。-c:只編譯不,只生成目標文件。-g:添加gdb調試選項。Linu*下C語言應用編程文件I/O編程多進程編程的根本知識,核心是fork、e*ec、wait三大系統(tǒng)的調用;〔可能需要補充操作系統(tǒng)進程并發(fā)運行的根本知識〕進程間通信的幾種方法:信號,管道,共享存,信號量,消息隊列?!沧钪匾氖切盘柡凸艿馈扯嗑€程編程的根底知識;網絡編程:socket編程,TCPsocket編程和UDPsocket編程;開發(fā)工具〔包括:編輯器vim、編譯器gcc、調試器gdb、工程管理工具autoconf、程序庫的制作等〕;編譯器vim的三種模式:切換到編輯模式的四種方式,編輯模式可以輸入任意容a光標向后移動一位i

當前位置o另起新行s刪除光標所在字符r替換光標所在字符2.尾行模式,用于保存容、查找替換、設置行號等等功能性操作:q

//quit退出vi編輯器:w//write保存修改的容:wq//保存并退出:q!//強制退出,當對文本容作了修改而不想要保存時:w!//強制保存,當沒有文本的寫權限時make和makefile文件:makefile定義了一系列的規(guī)則來指定,哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯,甚至于進展更復雜的功能操作〔因為makefile就像一個Shell腳本一樣,可以執(zhí)行操作系統(tǒng)的命令〕。makefile帶來的好處就是—“自動化編譯〞,一旦寫好,只需要一個make命令,整個工程完全自動編譯。makefile文件需要按照*種語法進展編寫,文件中需要說明如何編譯各個源文件并生成可執(zhí)行文件,要求定義源文件之間的依賴關系。make工具最主要也最根本的功能就是根據makefile文件中描述的源程序之間的相互關系來完成自動編譯、維護多源文件工程。Linu*下的常用命令Linu*刪除文件夾和文件的命令-r就是向下遞歸,不管有多少級目錄,一并刪除-f就是直接強行刪除,不作任何提示的意思刪除文件夾實例:rm-rf/var/log/d/access將會刪除/var/log/d/access目錄以及其下所有文件、文件夾刪除文件使用實例:rm-f/var/log/d/access.log將會強制刪除/var/log/d/access.log這個文件文件I/O編程:系統(tǒng)調用、API與系統(tǒng)命令之間的關系Linu*系統(tǒng)調用是指操作系統(tǒng)提供應用戶程序的一組“特殊〞接口,用戶程序可以通過這組“特殊〞接口來獲得操作系統(tǒng)核提供的特殊效勞。比方用戶可以通過文件系統(tǒng)相關的調用請求系統(tǒng)翻開文件、關閉文件或讀寫文件,可以通過時鐘相關的系統(tǒng)調用獲得系統(tǒng)時間或設置系統(tǒng)時間等。為了更好的保護核空間,將程序的運行空間分為核空間和用戶空間,它們運行在不同的級別上,在邏輯上是相互隔離的。在Linu*中,用戶程序不能直接訪問核提供的效勞,必須通過系統(tǒng)調用來使用核提供的效勞。用戶進程在通常情況下不允許訪問核數據,也無法使用核函數,它們只能在用戶空間操作用戶數據,調用用戶空間函數。Linu*中的用戶編程接口〔API〕遵循了UNI*中最流行的應用編程界面標準-POSI*標準?!策@些系統(tǒng)調用編程接口主要是通過C庫〔libc〕實現的?!尺@套標準定義了一系列API。在Linu*中〔Uni*也如此〕這些API主要是通過C庫〔libc〕實現的,它除了定義的一些標準的C函數外,一個很重要的任務就是提供了一套封裝例程〔wrapperroutine〕將系統(tǒng)調用在用戶空間包裝后供用戶編程使用??捎玫奈募蘒/O函數很多,包括:翻開文件、讀文件、寫文件等。大多數Linu*文件I/O只需要用到5個函數:open、read、write、lseek以及close。這5個函數是不帶緩存的I/O函數,它們是POSI*標準的組成局部。在C語言中也有文件I/O函數,例如:fread、fwrite、fprintf、fscanf等。這些函數是帶緩存的I/O函數,它們屬于ANSIC的組成局部。Linu*下系統(tǒng)調用、API、系統(tǒng)命令、核函數的區(qū)別與聯(lián)系系統(tǒng)調用:應用程序和核間的橋梁,是應用程序訪問核的入口點;但通常情況下,應用程序通過操作系統(tǒng)提供的API進展編程而不是使用系統(tǒng)調用直接編程;linu*的全部系統(tǒng)調用加起來大約只有250個左右。這些系統(tǒng)調用按照功能邏輯大致可分為“進程控制〞、“文件系統(tǒng)控制〞、“系統(tǒng)控制〞、“存管管理〞、“網絡管理〞、“socket控制〞、“用戶管理〞、“進程間通信〞幾類;可以使用man2syscalls命令查看系統(tǒng)調用的說明,或者到<核源碼目錄>/include/asm-i386/unistd.h源文件種找到它們的原本。1.系統(tǒng)調用在核里的主要用途:控制硬件;設置系統(tǒng)狀態(tài)或讀取核數據;進程管理2.什么的效勞應該存在于核,或者說什么功能應該在核而不是在用戶空間;〔如效勞是否必須獲得核數據;平安的角度;效率的角度等〕API:API常以C庫(libc)的形式提供,C庫提供了絕大局部API,每個系統(tǒng)調用在C庫中都有對應的封裝函數(通常封裝函數與系統(tǒng)調用的名稱一樣)。系統(tǒng)調用與C庫函數并不是一一對應的,有些C庫函數可能使用多個系統(tǒng)調用來實現,也有可能多個C庫函數使用同一個系統(tǒng)調用來實現,也有些C庫函數不使用任何系統(tǒng)調用來實現。系統(tǒng)命令:系統(tǒng)命令是使用Linu*提供的C庫函數實現的可執(zhí)行程序,可用strace查看命令執(zhí)行時所使用的系統(tǒng)調用。核函數:系統(tǒng)調用是用戶進入核的接口,它本身不是核函數,進入核后每個系統(tǒng)調用會找到自己對應的核函數(即系統(tǒng)調用效勞例程)從用戶的角度看,從底層往上看分別是:核函數,系統(tǒng)調用,API,系統(tǒng)命令核函數和系統(tǒng)調用的關系:核函數和普通函數很像,只不過在核中實現,因此要滿足一些核編程的要求。系統(tǒng)調用是一層用戶進入核的接口,它本身并非核函數,進入核后,不同的系統(tǒng)調用會找到對應到各自的核函數即,系統(tǒng)調用效勞例程。實際對請求效勞的是核函數而非調用接口〔系統(tǒng)調用〕。比方系統(tǒng)調用getpid實際就是調用核函數sys_getpid。Linu*下不帶緩存的I/O和帶緩存的I/O:概念:不帶緩存的I/O:UNI*的文件I/Oread、write是不帶緩存的,不帶緩存是指每個read、write都調用核的一個系統(tǒng)調用,它們是POSI*.1的組成局部。不是核不提供緩存,而是對于用戶層來說,沒有提供緩存,而對核來說還是有緩存的數據:數據流->核緩存->磁盤帶緩存的I/O:是指在用戶層上再建立了一層緩存區(qū)〔流緩存區(qū)〕,目的是為了減少read,write等系統(tǒng)調用的使用次數,降低系統(tǒng)開銷。帶緩存的I/O是指標準I/O庫,它由ANSIC標準說明,標準I/O庫代替用戶處理很多細節(jié),比方緩存分配、以優(yōu)化長度執(zhí)行I/O等,提供緩存的目的是為了盡量減少read和write的調用次數;數據:數據流->流緩存區(qū)->核緩存->磁盤例如:當用fwrite函數向磁盤寫數據時,先把數據寫入流緩沖區(qū)中,當到達一定條件,比方流緩沖區(qū)滿了,或刷新流緩沖,這時候才會把數據一次送往核提供的塊緩沖,再經塊緩沖寫入磁盤?!搽p重緩沖〕用數據流來形容兩者的差異:無緩存I/O操作的數據流:數據->核緩存區(qū)->磁盤標準I/O操作的數據流:數據->流緩存區(qū)->核緩存區(qū)->磁盤文件描述符對核而言,所有翻開文件都由文件描述符應用。文件描述符是一個非負整數。當翻開一個現存文件或創(chuàng)立一個新文件時,核向進程返回一個文件描述符。當讀、寫一個文件時,用open或create返回的文件描述符標識該文件,將其作為參數傳送給read或write。在windows環(huán)境下,文件描述符大體上相當于文件句柄。在POSI*.1應用程序中,整數0、1、2應被代換成符號常數:STDIN_FILENO代表標準輸入〔默認是鍵盤〕、標準輸出〔默認是屏幕〕、標準錯誤輸出〔默認是屏幕〕,這些常數都定義在頭文件<unistd.h>中。多進程編程進程是一個具有一定獨立功能的程序對*個數據集合的一次運行活動。進程的實體構造:進程控制塊〔PCB〕;程序段;數據段;PCB位于核的存里面的一塊區(qū)域,是操作系統(tǒng)中最重要的記錄型數據構造。PCB中記錄了操作系統(tǒng)所需的,用于描述進程進展情況及控制進程所需的全部信息。進程塊主要包括下述4方面的信息:進程描述信息處理機狀態(tài)信息進程調度信息:進程狀態(tài)、進程優(yōu)先級〔用于描述進程使用處理機的優(yōu)先級別的一個整數,優(yōu)先級別高的進程先獲得處理機〕、進程調度所需的其他信息〔如進程已等待CPU的時間總和、進程已執(zhí)行的時間總和等〕、事件〔指進程被阻塞的原因〕。進程控制信息:程序和數據的地址〔指出該進程的程序和數據所在的存或外存地址,以便再調度到該進程執(zhí)行時,能從中找到其程序和數據〕;進程同步和通信機制〔指實現進程同步和進程通信時所必須的機制,如消息隊列指針、信號量等。這些數據應全部或局部存放在PCB中〕。進程的三種狀態(tài):進程的三種根本狀態(tài):〔1〕就緒狀態(tài):進程已獲得除CPU外的所有必要資源,只等待CPU時的狀態(tài)。一個系統(tǒng)會將多個處于就緒狀態(tài)的進程排成一個就緒隊列?!?〕執(zhí)行狀態(tài):進程已獲CPU,正在執(zhí)行。單處理機系統(tǒng)中,處于執(zhí)行狀態(tài)的進程只一個;多處理機系統(tǒng)中,有多個處于執(zhí)行狀態(tài)的進程?!?〕阻塞狀態(tài):正在執(zhí)行的進程由于*種原因而暫時無法繼續(xù)執(zhí)行,便放棄處理機而處于暫停狀態(tài),即進程執(zhí)行受阻?!策@種狀態(tài)又稱等待狀態(tài)或封鎖狀態(tài)〕通常導致進程阻塞的典型事件有:請求I/O,申請緩沖空間等。進程間通信進程間通信有如下一些目的:數據傳輸共享數據通知事件資源共享的同步進程控制多線程編程初步線程是一個程序部可以被操作系統(tǒng)調度并發(fā)運行的任務。在很多情況下,完成相關任務的不同代碼間需要交換數據。如果采用多進程的方式,則通信就只能采用幾種進程間通信的方式,但無論是信號、管道、共享存,還是信號量,它們的操作都比擬繁雜,不直觀;而且大多數要使用核對象,數據要在用戶空間和核空間進展切換,開銷很大。但如果采用多線程方式,線程間的通信(數據交換)既直觀又效率高,例如可以使用共享的全局變量。和進程相比,線程是一種“節(jié)省〞的多任務操作方式。運行于一個進程中的多個線程,它們彼此之間使用一樣的地址空間,共享大局部數據,啟動一個線程所花費的空間遠小于啟動一個進程所花費的空間,而且,線程間彼此切換所需的時間也遠遠小于進程間切換所需的時間?!矒y(tǒng)計,總的來說,一個進程的開銷大約是一個線程開銷的30倍左右,當然,在具體的系統(tǒng)上,這個數據可能會有較大的區(qū)別〕常用的線程函數創(chuàng)立線程:pthread_createintpthread_create(pthread_t*tidp,constpthread_attr_t*attr,(void*)(*start_rtn)(void*),void*arg);假設線程創(chuàng)立成功,則返回0。假設線程創(chuàng)立失敗,則返回出錯編號,并且*thread中的容是未定義的。返回成功時,由tidp指向的存單元被設置為新創(chuàng)立線程的線程ID。attr參數用于指定各種不同的線程屬性。新創(chuàng)立的線程從start_rtn函數的地址開場運行,該函數只有一個萬能指針參數arg,如果需要向start_rtn函數傳遞的參數不止一個,則需要把這些參數放到一個構造中,然后把這個構造的地址作為arg的參數傳入。linu*下用C語言開發(fā)多線程程序,Linu*系統(tǒng)下的多線程遵循POSI*線程接口,稱為pthread。參數第一個參數為指向線程標識符的指針。第二個參數用來設置線程屬性。第三個參數是線程運行函數的起始地址。最后一個參數是運行函數的參數。當線程運行函數的參數不止一個時,則需要把這些參數放到一個構造中,然后將找個構造的地址當作參數傳輸參數。線程互斥鎖的初始化pthread_mute*_initintpthread_mute*_init(pthread_mute*_t*restrictmute*,constpthread_mute*attr_t*restrictattr);pthread_mute*_tmute*=PTHREAD_MUTE*_INITIALIZER;pthread_mute*_init()函數是以動態(tài)方式創(chuàng)立互斥鎖的,參數attr指定了新建互斥鎖的屬性。如果參數attr為空,則使用默認的互斥鎖屬性,默認屬性為快速互斥鎖?;コ怄i的屬性在創(chuàng)立鎖的時候指定,在Linu*Threads實現中僅有一個鎖類型屬性,不同的鎖類型在試圖對一個已經被鎖定的互斥鎖加鎖時表現不同。3.線程初始化條件變量函數pthread_cond_init〔〕;e*ternintpthread_cond_init((pthread_cond_t*cond,constpthread_condattr_t*cond_attr));其中cond是一個指向構造pthread_cond_t的指針,cond_attr是一個指向構造pthread_condattr_t的指針。構造pthread_condattr_t是條件變量的屬性構造,和互斥鎖一樣我們可以用它來設置條件變量是進程可用還是進程間可用,默認值是PTHREAD_PROCESS_PRIVATE,即此條件變量被同一進程的各個線程使用;如果選擇為PTHREAD_PROCESS_SHARED則為多個進程間各線程公用。注意初始化條件變量只有未被使用時才能重新初始化或被釋放。返回值:函數成功返回0;任何其他返回值都表示錯誤。釋放一個條件變量的函數為pthread_cond_destroy〔pthread_cond_t*cond〕。完畢線程:pthread_e*it//線程自行完畢〔自殺〕使用pthread_e*it等待線程完畢:pthread_joinpthread_create調用成功后,新生成的線程和老線程誰先被調度執(zhí)行,取決于OS,應用程序無法控制。因此,應用程序員如需等待指定線程完畢,需要使pthread_join。intpthread_join(pthread_tth,void**thread_return);th是要等待完畢的線程的標識。指針thread_return指向的位置存放的是終止線程的返回狀態(tài)。sched_yield()這個函數可以使另一個級別等于或高于當前線程的線程先運行。如果沒有符合條件的線程,則這個函數將會立刻返回,然后繼續(xù)執(zhí)行當前線程的程序。在成功完成之后返回零,否則返回-1.多線程的同步與互斥由于多個線程間極有可能回訪問共享的資源〔典型的是訪問同一個全局變量〕,因此多個線程間存在競爭,這就需要在多個線程間進展同步。互斥鎖多線程的同步采用加鎖的機制,類似于多進程間的信號量機制。在主線程中初始化鎖為解鎖狀態(tài)〔類似于初始化0-1信號量為1〕在編譯時初始化鎖為解鎖狀態(tài);在訪問共享對象前進展加速操作〔類似于對信號量執(zhí)行P操作〕;在訪問共享對象后進展解鎖操作〔類似于對信號量執(zhí)行V操作〕;信號量互斥鎖一個明顯的缺點是它只有兩種狀態(tài):鎖定和非鎖定。從本質上講,互斥鎖就是一個0-1信號量。因此當公共資源總量超過1時,互斥鎖就不能用于線程同步了,此時可以采用信號量。信號量的本質上是一個非負的整數計數器,它被用來控制對公共資源的訪問。當公共資源增加時,調用sem_post()函數增加信號量。只有當信號量值大于0時,才能使用公共資源,使用后,調用函數sem_wait()減少信號量。線程屬性創(chuàng)立線程時指定線程的屬性線程的綁定輕進程:可以理解為核線程,它位于用戶層和系統(tǒng)層之間。系統(tǒng)對線程資源的分配、對線程的控制是通過輕進程來實現的。一個輕進程可以控制一個或多個線程。默認情況下,啟動多少輕進程,哪些輕進程來控制哪些線程是由系統(tǒng)來控制的,這種狀況即稱為非綁定的。綁定:是*個線程固定的“邦〞在一個輕進程之上。被綁定的線程具有較高的響應速度,這是因為CPU時間片的調度是面向輕進程的,綁定的線程可以保證在需要的時候總有一個輕進程可用。通過設置被綁定的輕進程的優(yōu)先級和調度級可以使得綁定的線程滿足諸如實時反響之類的要求。設置線程綁定狀態(tài)的函數為:線程創(chuàng)立后改變屬性一個線程如果想殺死另一個線程的話,可以通過調用pthread_cancel來完成。類似于多進程中的kill。線程調度和優(yōu)先級設置線程是獨立執(zhí)行的。它們被分派到處理器核上,并執(zhí)行分給它們的任務。每個線程均有一個調度策略和優(yōu)先級,決定何時以及如何分配到處理器上。線程或線程組的調度策略可以使用這些函數通過屬性對象來設置:調用形式*include<pthread.h>*include<sched.h>intpthread_attr_setinheritsched(pthread_attr_t*attr,intinheritsched);voidpthread_attr_setschedpolicy(pthread_attr_t*attr,intpolicy);intpthread_attr_setschedparam(pthread_attr_t*restrictattr,conststructsched_param*restrictparam);pthread_attr_setinheritesched()用于確定如何設置線程的調度屬性,可以從創(chuàng)立者線程或從一個屬性對象來繼承調度屬性。inheritsched可以為如下值:PTHREAD_INHERIT_SCHED:線程調度屬性是從創(chuàng)立者線程繼承得到,attr的任何調度屬性都被忽略。PTHREAD_E*PLICIT_SCHED:線程調度屬性設置為屬性對象attr的調度屬性。如果inheritsched值是PTHREAD_E*PLICIT_SCHED,則pthread_attr_setschedpolicy()被用于設置調度策略,而pthread_attr_setschedparam()被用于設置優(yōu)先級。pthread_attr_setschedpolicy()設置線程屬性對象attr的調度策略。policy的值可以為在<sched.h>頭文件中定義的以下值。SCHED_FIFO:先進先出調度策略,執(zhí)行線程運行到完畢。SCHED_RR:輪詢調度策略,按照時

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論