




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1、第第2章章 嵌入式嵌入式Linux基礎基礎第二章第二章 嵌入式嵌入式LinuxLinux基基礎礎主要內(nèi)容主要內(nèi)容 第一節(jié) 構(gòu)建嵌入式Linux系統(tǒng)環(huán)境 第二節(jié) Linux C程序設計 第三節(jié) Linux多線程庫編程 第四節(jié) 進程創(chuàng)建以及進程間通信 學習方法與建議學習方法與建議本章將介紹和嵌入式Linux開發(fā)有關(guān)的基礎知識,主要包括三部分內(nèi)容:構(gòu)建嵌入式Linux操作系統(tǒng)開發(fā)環(huán)境,即了解嵌入式系統(tǒng)開發(fā)的相關(guān)細節(jié)和環(huán)境搭建;嵌入式系統(tǒng)開發(fā)基礎,C語言程序設計;線程和進程的程序?qū)崿F(xiàn)。本章的部分內(nèi)容在后續(xù)章節(jié)中會有進一步的應用。 內(nèi)容:內(nèi)容:一、交叉編譯一、交叉編譯 二、關(guān)于交叉編譯器二、關(guān)于交叉編譯
2、器 三、關(guān)于三、關(guān)于NFS第一節(jié)第一節(jié) 構(gòu)建嵌入式構(gòu)建嵌入式Linux系統(tǒng)環(huán)境系統(tǒng)環(huán)境 嵌入式系統(tǒng)一般是以應用為中心、以計算機技術(shù)為基礎、軟件硬件可裁剪、適應應用系統(tǒng)對功能、可靠性、成本、體積、功耗嚴格要求的專用計算機系統(tǒng)。嵌入式開發(fā)板的資源往往比較有限,沒有足夠的資源來運行開發(fā)調(diào)試工具。所以,通常嵌入式系統(tǒng)的軟件開發(fā)需要采用交叉編譯的方式。 交叉編譯是構(gòu)建嵌入式Linux系統(tǒng)環(huán)境過程中的重要一步。交叉編譯的環(huán)境建立在宿主機(host)上,而對應的開發(fā)板稱為目標機(target)。為了使宿主機上開發(fā)的程序(應用程序和驅(qū)動程序)能夠方便地下載到目標機上運行,一般還要在宿主機上配置好網(wǎng)絡,使其支持
3、NFS或tftp等網(wǎng)絡服務,從而達到兩臺機器之間的文件共享。第一節(jié)第一節(jié) 構(gòu)建嵌入式構(gòu)建嵌入式Linux系統(tǒng)環(huán)境系統(tǒng)環(huán)境 一、交叉編譯一、交叉編譯交叉編譯交叉編譯利用運行在某臺計算機(宿主機)上的編譯器編譯某個源程序,生成在另一臺機器(目標機)上運行的目標代碼的過程。交叉編譯是不得不產(chǎn)生的技術(shù)。因為目標機資源有限,無法運行編譯和調(diào)試工具,因此需要宿主機為之代勞。另外,在構(gòu)建嵌入式系統(tǒng)的過程中也需要交叉編譯目標機所需要的引導系統(tǒng)和操作系統(tǒng)內(nèi)核。因此,在嵌入式系統(tǒng)開發(fā)時,往往由宿主機開發(fā)程序,而目標機作為最后的執(zhí)行機。兩者在開發(fā)時需要交替結(jié)合進行。 在構(gòu)建交叉編譯環(huán)境的過程中,交叉編譯器(cros
4、s compilation tool chain)無疑是最重要的組成部分。在嵌入式系統(tǒng)開發(fā)過程中,由于嵌入式開發(fā)平臺的資源有限:例如常見的ARM開發(fā)平臺,其靜態(tài)存儲空間僅有32MB,CPU主頻也僅為203Mhz。這樣的資源不足以完成本機編譯(native compilation),因此交叉編譯器應運而生??梢允褂?v參數(shù)查看編譯器的相關(guān)信息。由下圖可知,armv4l-unknown-linux-gcc的版本是2.95.2。 第一節(jié)第一節(jié) 構(gòu)建嵌入式構(gòu)建嵌入式Linux系統(tǒng)環(huán)境系統(tǒng)環(huán)境 二、關(guān)于交叉編譯器二、關(guān)于交叉編譯器 包括gcc在內(nèi)的語言編譯工具是能夠把某種以數(shù)字和符號為內(nèi)容的高級編程語言
5、轉(zhuǎn)換成機器語言指令的集合。因此在編譯過程中,編譯器還必需聯(lián)合其它一些輔助工具才能工作。這些輔助編譯工具包括:第一節(jié)第一節(jié) 構(gòu)建嵌入式構(gòu)建嵌入式Linux系統(tǒng)環(huán)境系統(tǒng)環(huán)境 二、關(guān)于交叉編譯器二、關(guān)于交叉編譯器 解釋程序解釋程序(Interpreter)其本身也是一種語言翻譯工具。它能夠直接執(zhí)行源程序,簡單且方便移植,但是執(zhí)行速度比編譯器慢。匯編器(匯編器(Assembler)用于特定計算機上的匯編語言翻譯程序。連接器(連接器(Linker)能夠把在不同的目標文件中編譯或匯編的代碼收集到一個可直接執(zhí)的文件中,同時也能夠連接目標程序和相應的標準庫函數(shù)代碼。裝載器(裝載器(Loader)裝載器可處理所
6、有與指定的基地址或起始地址相關(guān)的可復位的地址,這樣能夠使得編譯過程更加靈活。預處理器預處理器(Preprocessor)編譯開始時被調(diào)用。專門負責刪除注釋和執(zhí)行宏替換等工作。調(diào)試器(調(diào)試器(Debugger) 用于調(diào)試目標代碼,以排除代碼中存在的錯誤。 在嵌入式系統(tǒng)開發(fā)過程中,由于可執(zhí)行程序的編譯過程和執(zhí)行過程分別在宿主機和目標機上完成,因此實現(xiàn)宿主機和目標機之間的實時交互能夠大幅度提高嵌入式系統(tǒng)開發(fā)的效率。由于目標機也帶有操作系統(tǒng),因此可以通過實現(xiàn)不同機器之間的網(wǎng)絡共享來完成實時交互。 NFS(Network File System,網(wǎng)絡文件系統(tǒng)),網(wǎng)絡文件系統(tǒng)) 允許一個操作系統(tǒng)在網(wǎng)絡上與
7、他人共享目錄和文件。通過使用NFS,用戶可以像訪問本地文件一樣訪問遠程系統(tǒng)上的文件,即使是不同的系統(tǒng)或者通信協(xié)議也能夠完成共享。 第一節(jié)第一節(jié) 構(gòu)建嵌入式構(gòu)建嵌入式Linux系統(tǒng)環(huán)境系統(tǒng)環(huán)境 三、關(guān)于三、關(guān)于NFS 相關(guān)操作 如下: 如果不知道宿主機的Linux系統(tǒng)是否已經(jīng)運行NFS,可以使用如下命令查看:rootlocalhost root# netstat -l |grep nfsudp 0 0 *:nfs *:* 如果沒有啟動NFS,可以使用如下命令啟動:rootlocalhost root# service nfs restart關(guān)閉 NFS mountd: 確定 關(guān)閉 NFS 守護進
8、程: 確定 Shutting down NFS quotas: 確定 關(guān)閉 NFS 服務: 確定 啟動 NFS 服務: 確定 Starting NFS quotas: 確定 啟動 NFS 守護進程: 確定 啟動 NFS mountd: 確定 第一節(jié)第一節(jié) 構(gòu)建嵌入式構(gòu)建嵌入式Linux系統(tǒng)環(huán)境系統(tǒng)環(huán)境 三、關(guān)于三、關(guān)于NFS 相關(guān)操作 如下: 對于需要export的nfs目錄,可以修改/etc/exports文件:rootlocalhost root# vi /etc/exports/arm2410s/ 192.168.0.*(rw,insecure,sync,no_root_squash)
9、保存退出之后,向內(nèi)核告知所要export的目錄:rootlocalhost root# exportfs -ravexporting 192.168.0.*:/arm2410s 全部完成后,可以測試一下NFS是否可用:rootlocalhost root# mkdir /testrootlocalhost root# mount -o nolock 21:/arm2410s/ /test/如果掛載成功,則進入test目錄,所顯示內(nèi)容就是arm2410s目錄的內(nèi)容。第一節(jié)第一節(jié) 構(gòu)建嵌入式構(gòu)建嵌入式Linux系統(tǒng)環(huán)境系統(tǒng)環(huán)境 三、關(guān)于三、關(guān)于NFS 第二節(jié)第二節(jié) Linux
10、 C程序設計程序設計一、一、C程序設計概述程序設計概述 簡單介紹Linux下的C程序設計二、二、Makefile介紹介紹 介紹Makefile的使用規(guī)則三、三、Makefile中的變量中的變量 陳述Makfeile中的多種變量 四、四、Makefile隱含規(guī)則隱含規(guī)則 介紹Makefile中的隱含規(guī)則 在Linux下,一般使用GNU C編譯器(GCC)進行應用程序的編譯。GNU C編譯器(GCC)是一款功能強大的ANSI C兼容編譯器 ,一般存放在/usr/bin目錄下;其頭文件一般存放在/usr/include及其下級子目錄里;而標準的庫文件則存放在/lib或/usr/lib子目錄里。gcc
11、 命令的基本用法如下所示:gcc options filenames make是一個命令工具,它讀入Makefile的指令并按照其制定的規(guī)則執(zhí)行。Makefile文件中描述整個工程所有文件的編譯順序、編譯規(guī)則,并且擁有自己的書寫格式、關(guān)鍵字和函數(shù);而且在Makefile中可以使用系統(tǒng)shell所提供的任何命令來完成想要的工作,因此能夠大大提高了編譯程序的效率。通過其“自動化編譯”的規(guī)則,只需要一個make命令,整個工程就可以自動完成全部編譯工作,因此在IDE開發(fā)環(huán)境中得到廣泛應用,已經(jīng)成為一種工程方面的編譯方法。 第二節(jié)第二節(jié) Linux C程序設計程序設計 一、一、C程序設計概述程序設計概述
12、 默認情況下,GNU make工具在當前工作目錄中按如下順序搜索makefile:GNUmakefile - makefile - Makefile 雖然Makefile作為規(guī)則的優(yōu)先等級較低,不過由于Makefile的首字母大寫,因此在當前目錄下會優(yōu)先顯示,所以程序員往往會采用Makefile作為makefile文件。如果要使用其他文件作為 makefile,則可采用以下方式:$ make -f Makefile.debug第二節(jié)第二節(jié) Linux C程序設計程序設計 二、二、Makefile介紹介紹 makefile的基本結(jié)構(gòu)如下:target:dependency dependency(
13、tab)它包含target、dependency和command三個部分。具體如下所示: 一個目標(一個目標(target)最終需要創(chuàng)建的文件,包括可執(zhí)行文件或者目標驅(qū)動文件等。當然目標也可以是需要執(zhí)行的動作,如“clean”等。 一個或多個依賴文件(一個或多個依賴文件(dependency)在創(chuàng)建target時需要用到的文件列表。一系列命令一系列命令(command) make執(zhí)行的動作,即創(chuàng)建target文件所需要執(zhí)行的步驟。通常是把指定文件編譯成目標文件的編譯命令,每個命令占一行,且每個命令行的起始字符必須為TAB字符。 第二節(jié)第二節(jié) Linux C程序設計程序設計 二、二、Makefi
14、le介紹介紹 編譯的具體過程是 make工具首先讀取makefile中的規(guī)則,然后檢查該規(guī)則中的依賴文件與目標文件的時間戳哪個更新一些,并根據(jù)規(guī)則鏈由下至上依次執(zhí)行編譯過程,直到最終的可執(zhí)行文件被重新連接完成為止。 第二節(jié)第二節(jié) Linux C程序設計程序設計 二、二、Makefile介紹介紹 Makefile里的變量類似一個環(huán)境變量。這些變量對大小寫敏感,一般使用大寫字母。 下面給出一個具體的makefile:OBJS=prog.o code.o#定義變量定義變量OBJSCC=gcc #定義變量定義變量CCtest:$(OBJS)$(CC) o test $(OBJS) #gcc o tes
15、t prog.o code.oprog.o:prog.c prog.h code.h$(CC) c prog.c o prog.ocode.o:code.c code.h$(CC) c code.c o code.oclean:rm f *.o 顯然,在上述例子中,用戶自定義了CC和OBJS兩個變量,并且在之后的規(guī)則中使用$()符號對其內(nèi)容進行引用。 第二節(jié)第二節(jié) Linux C程序設計程序設計 三、三、Makefile中的變量中的變量 除用戶自定義的變量外,make還允許使用如下類型的變量: 環(huán)境變量環(huán)境變量 在啟動時,make讀取系統(tǒng)當前已定義的環(huán)境變量,并且創(chuàng)建與之同名同值的變量,因此用
16、戶可以像在Shell中一樣在Makefile中引用環(huán)境變量。需要注意的是,如果用戶在Makefile中定義了同名變量,那么用戶自定義變量將覆蓋同名的環(huán)境變量。第二節(jié)第二節(jié) Linux C程序設計程序設計 三、三、Makefile中的變量中的變量 預定義變量預定義變量$*不包含擴展名的目標文件名稱。$+所有的依賴文件,以空格分開,并以出現(xiàn)的先后為序,包含重復的依賴文件。$第一個依賴文件的名稱。$?所有依賴文件以空格分開,這些依賴文件修改日期比目標創(chuàng)建日期晚 。$目標的完整名稱。$所有的依賴文件,以空格分開,不包含重復的依賴文件。$%如果目標是歸檔成員,則該變量表示目標的歸檔成員名稱。AR歸檔維護
17、程序的名稱,默認值為 ar。ARFLAGS歸檔維護程序的選項。AS匯編程序的名稱,默認值為 as。ASFLAGS匯編程序的選項。CCC 編譯器的名稱,默認值為 cc。CFLAGSC 編譯器的選項。CPPC 預編譯器的名稱,默認值為 $(CC) -E。 CPPFLAGSC 預編譯的選項。 CXX C+ 編譯器的名稱,默認值為 g+。 CXXFLAGSC+ 編譯器的選項。FCFORTRAN 編譯器的名稱,默認值為 f77。FFLAGSFORTRAN 編譯器的選項。第二節(jié)第二節(jié) Linux C程序設計程序設計 三、三、Makefile中的變量中的變量 在上述例子中,幾個產(chǎn)生目標文件的命令都是從C源文
18、件和相關(guān)文件通過編譯產(chǎn)生目標文件。實際上,make完全可以更簡潔一些:make有一些稱作隱含規(guī)則的內(nèi)置的規(guī)則,這些規(guī)則告訴make當某些命令沒有被完整給出時應該怎樣執(zhí)行。 例如,把生成prog.o和code.o的命令從規(guī)則中刪除,make將會查找隱含規(guī)則,并執(zhí)行一個適當?shù)拿?。由于這些命令往往會使用一些變量,因此可以通過改變這些變量來定制make。像在前面的例子中所定義的那樣,make使用變量CC來定義編譯器,并且傳遞變量CFLAGS(編譯器參數(shù))、CPPFLAGS(C語言預處理器參數(shù))、TARGET_ARCH(目標機器的結(jié)構(gòu)定義)給編譯器,然后加上編譯參數(shù)-c,變量$(第一個依賴文件名),改
19、名參數(shù)-o以及變量$(目標文件名)。第二節(jié)第二節(jié) Linux C程序設計程序設計 四、四、Makefile隱含規(guī)則隱含規(guī)則 綜上所述,一個C編譯的具體命令將會是:$ CC $ CFLAGS $ CPPFLAGS $ TARGET_ARCH c $ -o $ 使用隱含規(guī)則的例子如下所示:OBJS=prog.o code.oCC=gcctest:$(OBJS)$(CC) o $ $prog.o:prog.c prog.h code.hcode.o:code.c code.hclean:rm f *.o第二節(jié)第二節(jié) Linux C程序設計程序設計 四、四、Makefile隱含規(guī)則隱含規(guī)則 第三節(jié)第三
20、節(jié) Linux多線程庫編程多線程庫編程 一、一、 多線程多線程 二二 、多線程介紹、多線程介紹 三三 、常用操作生產(chǎn)者、常用操作生產(chǎn)者-消費者模型簡述消費者模型簡述四、簡述緩沖區(qū)的具體操作四、簡述緩沖區(qū)的具體操作 五、幾個線程五、幾個線程API 第三節(jié)第三節(jié) Linux多線程庫編程多線程庫編程 一、多線程一、多線程 計算機在運行時其執(zhí)行過程從大到小可以分為作業(yè)、進程和線程三個等級。所謂線程,是系統(tǒng)能夠獨立調(diào)度和分派的最基本單位。線程自己并不擁有系統(tǒng)資源,只是在運行的時候占用一點必不可少的資源。如果在一個程序中同時運行多個線程來完成不同的工作,則稱之為多線程多線程。 顯然,多線程可以更方便的體現(xiàn)
21、“并行”特性,而且由于線程的輕量級,因此能夠大大提高系統(tǒng)效率;而且在多CPU的硬件前提下更可以充分利用多核資源,因此被引入到操作系統(tǒng)之中。 Linux系統(tǒng)下的多線程遵循POSIX線程接口,稱之為pthread。多線程編程的源程序必須包含頭文件pthread.h,因為線程庫libpthread.a并不屬于Linux系統(tǒng)的默認庫,因此在編譯時需要加上l pthread參數(shù)。 /* exampthread.c*/#include #include void thread(void)int i;for(i=0;i3;i+)printf(This is a pthread.n);int main(voi
22、d)第三節(jié)第三節(jié) Linux多線程庫編程多線程庫編程 二、多線程介紹二、多線程介紹 pthread_t id;int i,ret;ret=pthread_create(&id,NULL,(void *) thread,NULL);if(ret)printf (Create pthread error!n);exit (1);for(i=0;i3;i+)printf(This is the main process.n);pthread_join(id,NULL);return (0);在宿主機上用如下命令編譯該程序,就可以生成可執(zhí)行文件。#armv4l-unknown-linux-gcc l
23、pthreado exampthread exampthread.c將生成的exampthread文件下載至開發(fā)板。 或者可能出現(xiàn)如下結(jié)果:This is a pthread.This is the main process.This is a pthread.This is the main process. This is a pthread.This is the main process.運行之后可能顯示如下結(jié)果:This is the main process.This is a pthread.This is the main process.This is the main pr
24、ocess.This is a pthread.This is a pthread.第三節(jié)第三節(jié) Linux多線程庫編程多線程庫編程 二、多線程介紹二、多線程介紹 在上例中首先聲明了一個pthread_t型變量。pthread_t類型類型在頭文件/usr/include/bits/pthreadtypes.h中定義:typedef unsigned long int pthread_t; 之后使用到的函數(shù)pthread_create用來創(chuàng)建一個線程,其原型為:extern int pthread_create _P (pthread_t *_thread, _const pthread_att
25、r_t *_attr, void *(*_start_routine) (void *), void *_arg); 第一個參數(shù)為指向線程標識符的指針,第二個參數(shù)用來設置線程屬性,第三個參數(shù)是線程運行函數(shù)的起始地址,最后一個參數(shù)為運行函數(shù)的參數(shù)。 在該例中,函數(shù)thread不需要參數(shù),所以最后一個參數(shù)設為空指針;第二個參數(shù)也設為空指針,這樣將生成默認屬性的線程。當創(chuàng)建線程成功時,函數(shù)返回0,若不返回0則說明創(chuàng)建線程失敗。常見的錯誤返回代碼為EAGAIN和EINVAL,前者表示系統(tǒng)限制創(chuàng)建新的線程(例如線程數(shù)目過多了);后者表示第二個參數(shù)代表的線程屬性值非法。創(chuàng)建線程成功后,新創(chuàng)建的線程則運行第
26、3個參數(shù)和第4個參數(shù)確定的函數(shù),原來的線程則繼續(xù)運行下一行代碼。 第三節(jié)第三節(jié) Linux多線程庫編程多線程庫編程 二、多線程介紹二、多線程介紹 使用的另外一個函數(shù)pthread_join用來等待一個線程的結(jié)束。該函數(shù)的原型為:extern int pthread_join _P (pthread_t _th, void *_thread_return); 其中,第一個參數(shù)為被等待的線程標識符,第二個參數(shù)為一個用戶定義的指針,它可以用來存儲被等待線程的返回值。由于該函數(shù)是一個線程阻塞的函數(shù),調(diào)用它的函數(shù)將一直等待,直到被等待的線程結(jié)束為止。當函數(shù)返回時,被等待線程的資源被收回。 結(jié)束一個線程有
27、兩種方法,一種方法如上例所示,函數(shù)結(jié)束也就意味著調(diào)用它的線程結(jié)束;另一種方法是通過函數(shù)pthread_exit來實現(xiàn)。其函數(shù)原型為:extern void pthread_exit _P (void *_retval) _attribute_ (_noreturn_); 唯一的參數(shù)是函數(shù)的返回代碼,因此只要pthread_join中的第二個參數(shù)thread_return不是NULL,那么這個值將被傳遞給thread_return。這里要注意的是,一個線程不能被多個線程等待,否則第一個接收到信號的線程成功返回,其余調(diào)用pthread_join的線程則返回錯誤代碼ESRCH。 第三節(jié)第三節(jié) Lin
28、ux多線程庫編程多線程庫編程 二、多線程介紹二、多線程介紹 在上例中,前后兩次的運行結(jié)果不一樣,這是兩個線程競爭CPU資源而導致的,說明線程執(zhí)行具有無序性。也就是說,并發(fā)運行線程的相對執(zhí)行順序是不確定的,在線程之間沒有數(shù)據(jù)共享的情況下,幾個線程執(zhí)行順序可以是隨機的。但是,當兩個或者兩個以上的線程共享數(shù)據(jù)時,線程隨機執(zhí)行就會產(chǎn)生錯誤。這時就需要某種機制來進行調(diào)整。當某線程執(zhí)行訪問共享數(shù)據(jù)區(qū)的某段程序時,不允許其他線程并發(fā)執(zhí)行,這就是多線程的同步機制。 操作系統(tǒng)提出了多個機制對線程的執(zhí)行順序進行限制,包括互斥鎖和條件變量等機制?;コ怄i用來保證共享數(shù)據(jù)操作的完整性。每個對象都有一個對應的稱為“互斥鎖
29、”的標記,而該標記能夠保證在任一時刻只有一個線程訪問該對象。條件變量能夠協(xié)助控制互斥鎖,滿足多線程控制機制。在這里將引入生產(chǎn)者-消費者模型對多線程的管理機制進行描述。第三節(jié)第三節(jié) Linux多線程庫編程多線程庫編程 三、常用操作生產(chǎn)者三、常用操作生產(chǎn)者-消費者模型簡述消費者模型簡述 在生產(chǎn)者-消費者模型中,主程序分別啟動了生產(chǎn)者線程和消費者線程。其中生產(chǎn)者線程不停地寫入共享的循環(huán)緩沖區(qū),而消費者線程則不停地從緩沖區(qū)中取出數(shù)據(jù)。 第三節(jié)第三節(jié) Linux多線程庫編程多線程庫編程 三、常用操作生產(chǎn)者三、常用操作生產(chǎn)者-消費者模型簡述消費者模型簡述 在生產(chǎn)者寫入緩沖區(qū)時,首先要獲得互斥鎖,并且判斷緩
30、沖區(qū)是否為滿,也就是判斷寫指針+1后是否等于讀指針,如果相等則進入等待狀態(tài),等候條件變量notfull發(fā)出信號;如果判斷條件不等,則向緩沖區(qū)寫一個整數(shù),同時設置條件變量notempty。最后釋放互斥鎖。 當消費者從緩沖區(qū)讀數(shù)時,首先要獲得互斥鎖,并且判斷緩沖區(qū)是否為空,也就是判斷寫指針是否等于讀指針,如果相等則進入等待狀態(tài),等候條件變量notempty發(fā)出信號;如果判斷結(jié)果為不等,則從緩沖區(qū)讀出一個整數(shù),同時設置條件變量notfull。最后釋放互斥鎖。 第三節(jié)第三節(jié) Linux多線程庫編程多線程庫編程 四、簡述緩沖區(qū)的具體操作四、簡述緩沖區(qū)的具體操作 條件變量初始化條件變量初始化int pth
31、read_cond_init (pthread_cond_t * cond, _const pthread_condattr_t * cond_attr) 第一個參數(shù)為指向結(jié)構(gòu)pthread_cond_t的指針,即條件變量名。第二個參數(shù)為指向結(jié)構(gòu)const pthread_condattr_t的指針,用來設置該條件變量是進程內(nèi)可用還是進程間可用。在該例中默認值是PTHREAD_PROCESS_PRIVATE,即該條件變量可被同一個進程內(nèi)的各個線程使用。 條件變量喚醒條件變量喚醒extern int pthread_cond_signal (pthread_cond_t *_cond) 它用來釋
32、放被阻塞在一個條件變量cond上的線程。如果條件變量cond阻塞的是多線程的話,喚醒哪一個線程則是由線程的調(diào)度策略來決定的。第三節(jié)第三節(jié) Linux多線程庫編程多線程庫編程 五、幾個線程五、幾個線程API 條件變量阻塞條件變量阻塞extern int pthread_cond_wait (pthread_cond_t *_restrict_cond,pthread_mutex_t *_restrict _mutex) 線程解開mutex指向的鎖并被條件變量cond阻塞。該線程可以被pthread_cond_signal喚醒,但是條件變量只起阻塞和喚醒線程的作用。線程被喚醒后,它將重新檢查判斷條
33、件是否滿足,如果還不滿足,則線程應該仍阻塞在這里,等待下一次喚醒。因此,這個過程一般用while語句實現(xiàn)。 互斥鎖初始化互斥鎖初始化pthread_mutex_init (pthread_mutex_t *mp,_const pthread_mutexattr_t *mattr) 當輸入?yún)?shù)mattr為空指針時,該函數(shù)以默認值初始化由參數(shù)mp指定的互斥鎖。當輸入?yún)?shù)mattr指向一個互斥鎖屬性對象時,該函數(shù)用來創(chuàng)建一個指定屬性的互斥鎖,其屬性為參數(shù)mattr指向的互斥鎖屬性對象的屬性。初始化一個互斥鎖之后,該互斥鎖處在解鎖狀態(tài)。第三節(jié)第三節(jié) Linux多線程庫編程多線程庫編程 五、幾個線程五、
34、幾個線程API 互斥鎖鎖定互斥鎖鎖定int pthread_mutex_lock (pthread_mutex_t *_mutex) 鎖定mutex參數(shù)指向的互斥鎖對象。當這個函數(shù)返回時,相應的互斥鎖被鎖定,調(diào)用pthread_mutex_lock函數(shù)的線程將成為這個互斥鎖的擁有者。如果此時這個互斥鎖被其他線程所擁有,那么這個線程將一直被阻塞,直到獲得這個互斥鎖。 互斥鎖解鎖互斥鎖解鎖int pthread_mutex_unlock (pthread_mutex_t *_mutex) 解開已經(jīng)鎖定的互斥鎖。當使用pthread_mutex_unlock解開一個互斥鎖時,如果有多個線程被該互斥鎖
35、阻塞,那么系統(tǒng)將根據(jù)調(diào)度策略決定由哪個線程獲得該互斥鎖。一般是按照優(yōu)先級高低來釋放阻塞線程。 第三節(jié)第三節(jié) Linux多線程庫編程多線程庫編程 五、幾個線程五、幾個線程API 第四節(jié)第四節(jié) 進程創(chuàng)建以及進程間通信進程創(chuàng)建以及進程間通信一、進程概述一、進程概述 二、進程的相關(guān)函數(shù)二、進程的相關(guān)函數(shù) 三、信號概述三、信號概述 四、信號的相關(guān)函數(shù)四、信號的相關(guān)函數(shù) 五、管道概述五、管道概述 六、管道相關(guān)函數(shù)六、管道相關(guān)函數(shù) 第四節(jié)第四節(jié) 進程創(chuàng)建以及進程間通信進程創(chuàng)建以及進程間通信 一、進程概述一、進程概述 在一個操作系統(tǒng)中,每個正在運行的工作都可以稱為進程(process)。它包括進程標識符和相關(guān)
36、的數(shù)據(jù),相關(guān)數(shù)據(jù)又包含進程變量、外部變量以及進程堆棧等。當一個進程啟動之后,系統(tǒng)會指定一個唯一的數(shù)值來作為該進程的進程標識符,即PID。 在Linux系統(tǒng)下,可以使用ps命令 查看進程。ps命令用來顯示系統(tǒng)中 正在運行的進程及其狀態(tài) 如果想查看所有進程及其它們的CPU、內(nèi)存占用率以及所屬用戶等信息,可以用top命令 在Linux系統(tǒng)中,進程的相關(guān)函數(shù)包括:getpid():用來獲得當前進程的進程標識符。返回當前進程的pid。extern _pid_t getpid (void) _THROW;getppid():用來取得父進程的進程標識符。返回當前進程的父進程的pid。extern _pid_
37、t getppid (void) _THROW;exec():創(chuàng)建新進程來取代舊進程,此時新進程的PID數(shù)值和舊進程的PID數(shù)值相同。以上三個函數(shù)都在/usr/include/unistd.h中=定義。其中,exec()函數(shù)族運行成功不會返回,運行失敗則返回-1。該函數(shù)族包括如下函數(shù):extern int execv (_const char *_path, char *_const _argv) _THROW;extern int execle (_const char *_path, _const char *_arg, .) _THROW;extern int execl (_const
38、 char *_path, _const char *_arg, .) _THROW;extern int execvp (_const char *_file, char *_const _argv) _THROW;extern int execlp (_const char *_file, _const char *_arg, .) _THROW;第四節(jié)第四節(jié) 進程創(chuàng)建以及進程間通信進程創(chuàng)建以及進程間通信 二、進程的相關(guān)函數(shù)二、進程的相關(guān)函數(shù) system():該函數(shù)可以使用系統(tǒng)的函數(shù)庫來建立新進程。使用格式如下:int system(const char *string);即可以將/bi
39、n/sh下的string命令行傳到execve函數(shù)中,之后運行該程序即相當于運行string字符串所代表的命令。該函數(shù)調(diào)用/bin/sh時如果失敗則函數(shù)返回127;其他失敗狀況則函數(shù)返回-1;如果自變量string為空指針則返回非零值。fork():某個父進程可以復制多個子進程的操作。該函數(shù)用來產(chǎn)生新的子進程,而調(diào)用fork函數(shù)的進程則稱為父進程。子進程會復制父進程的數(shù)據(jù),并且繼承父進程的各種參數(shù),但是由于子進程和父進程并不使用相同的內(nèi)存空間,所以并不同步。如果創(chuàng)建成功,則在父進程中會返回新建立的子進程代碼(PID),子進程中成功返回0,失敗則返回-1。 extern _pid_t fork
40、(void) _THROW;exit():用來終止進程。extern void exit (int _status)status為進程的退出狀態(tài)。如果為0,則表示進程成功退出;否則如果非0則表示出錯。第四節(jié)第四節(jié) 進程創(chuàng)建以及進程間通信進程創(chuàng)建以及進程間通信 二、進程的相關(guān)函數(shù)二、進程的相關(guān)函數(shù) wait():該函數(shù)能夠暫停父進程的運行,使其等待子進程。當子進程運行完畢之后,等待中的父進程將會重新運行。不過如果有多個子進程在運行,則當?shù)谝粋€子進程完成并返回,則父進程開始重新執(zhí)行。extern _pid_t wait (_WAIT_STATUS _stat_loc) _THROW;wait()函
41、數(shù)運行成功之后返回子進程PID,如果失敗則返回-1。waitpid():該函數(shù)能夠暫停當前進程的運行,使其等待子進程。當子進程運行完畢之后,等待中的父進程將會重新運行。waitpid()函數(shù)運行成功之后返回子進程PID,如果失敗則返回-1。extern _pid_t waitpid (_pid_t _pid, int *_stat_loc, int _options) _THROW; 函數(shù)wait()和waitpid()都用于清除zombie進程。所謂zombie進程,是指已經(jīng)結(jié)束運行,卻還沒有被清除的進程。當父進程結(jié)束了之后,子進程有可能還沒有結(jié)束,這樣的話子進程就會作為zombie進程而沒
42、有被清除。因此,可以在父進程中調(diào)用wait()或者waitpid()函數(shù)以在父進程結(jié)束之前自動清除子進程,保證清除zombie進程。 第四節(jié)第四節(jié) 進程創(chuàng)建以及進程間通信進程創(chuàng)建以及進程間通信 二、進程的相關(guān)函數(shù)二、進程的相關(guān)函數(shù) 由于進程的運行和安排具有無序性,其具體操作過程都是由操作系統(tǒng)進行統(tǒng)籌,因此有時需要人為對進程進行一定的順序化處理,這是通過在進程之間進行通信實現(xiàn)的。 在進程之間的通信方法中,信號是常用的方法之一。進程之間可以通過信號來通知異步事件的發(fā)生。信號本身并不直接攜帶信息,但是每種信號都有特定的含義。理解信號的各種含義之后,就可以編寫信號處理函數(shù)來實時響應信號的發(fā)生。當信號產(chǎn)
43、生之后,內(nèi)核會自動將信號分送到相應的進程之中。如果編寫了相應的信號處理函數(shù),則可以在接受這些信號之后進行相關(guān)的處理,非常方便。第四節(jié)第四節(jié) 進程創(chuàng)建以及進程間通信進程創(chuàng)建以及進程間通信 三、信號概述三、信號概述常見的信號名稱及其含義如下表所示 信號名稱信號含義SIGALRM定時器計時完成信號SIGINT中斷信號(CTRL+C)SIGQUIT退出信號(CTRL+)SIGCHILD子進程結(jié)束信號SIGTERM該信號由系統(tǒng)提供,用來終止進程的運行SIGUSR1 / SIGUSR2用戶保留自行發(fā)送信號SIGKILL該信號在進程之間發(fā)送,接收信號的進程將終止運行SIGSTOP該信號可以使進程暫時終止運行
44、第四節(jié)第四節(jié) 進程創(chuàng)建以及進程間通信進程創(chuàng)建以及進程間通信 三、信號概述三、信號概述signal():用來接收一個指定類型的信號,并調(diào)用相關(guān)的信號處理函數(shù)。void (*signal (int sig, void (*func)(int)(int)函數(shù)會根據(jù)sig指定的信號進行處理。當相關(guān)信號到達之后,就會自動調(diào)轉(zhuǎn)到func指定的函數(shù)中運行。運行結(jié)束后,會返回到信號處理函數(shù)的函數(shù)指針,如果有錯誤發(fā)生,則返回-1。signal的參數(shù)說明如表2-4所示。第四節(jié)第四節(jié) 進程創(chuàng)建以及進程間通信進程創(chuàng)建以及進程間通信 四、信號的相關(guān)函數(shù)四、信號的相關(guān)函數(shù) 參數(shù)說明sig用來指定相應的信號,但是不包括SI
45、GKILL和SIGSTOP。func信號處理函數(shù)的函數(shù)指針,表示對信號的處理方式。一般來說,參數(shù)func除了表示指定信號處理函數(shù)外,還可以表示兩個常量常量說明SIG_IGN表示要忽略的信號。SIG_DFL表示要恢復系統(tǒng)對信號的默認處理功能alarm():設置SIGALRM信號在經(jīng)過參數(shù)指定的秒數(shù)之后,傳送給當前的進程。extern unsigned int alarm (unsigned int _seconds) _THROW;kill():將sig參數(shù)所指定的信號傳送給pid參數(shù)所指定的進程。extern int kill (_pid_t _pid, int _sig) _THROW;其中pid參數(shù)可以是某個PID,也可以是如表2-6所示的數(shù)值:pid參數(shù)的含義pid說明pid=0信號被發(fā)送到和當前進程位于相同進程組的所有進程pid=-1信號按照pid從高到低的順序發(fā)送給所有的進程pid-1信號發(fā)送給進程組號為pid絕對值的所有進程pause():該函數(shù)會暫停當前的進程,直到接收到信號之后再繼續(xù)運行。該
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年北京貨運從業(yè)資格證考試模擬題庫
- sabr交班培訓課件
- 綾致培訓課件
- 安保技能培訓課件
- 晉升店長培訓課件
- 部門工作計劃開頭
- 模特培訓 基礎教程課件
- 小學語文編制題目及答案
- 武威市涼州技工學校招聘真題
- 2024年南平建甌市建州技術(shù)學校招聘考試真題
- 環(huán)保相關(guān)知識培訓課件
- 護理事業(yè)十五五發(fā)展規(guī)劃(2026-2030)
- 2025年隨州國投集團公開招聘42名工作人員筆試參考題庫附帶答案詳解
- 2025年3月10日吉林省紀委監(jiān)察廳遴選面試真題及解析
- 2025年 內(nèi)蒙古能源集團所屬單位招聘考試筆試試題(含答案)
- 2025年“安康杯”安全知識競賽題庫(含答案)
- 2025年江西省高考物理真題
- CJ/T 463-2014薄壁不銹鋼承插壓合式管件
- 風電場安全管理制度
- T/SHPTA 071.2-2023高壓電纜附件用橡膠材料第2部分:半導電橡膠材料
- 2025年鎢合金項目市場調(diào)查研究報告
評論
0/150
提交評論