目錄
- 選擇
- 填空
- 簡答題
- 編程題
選擇
1.linux 中把磁區和目錄對應的程序叫做( ), 掛載
2.信號是在軟體層次上對()機制的一種模擬, 是一種異步通信方式,
中斷
3.用 GCC 編譯程序可以被細分為四個階段:( )
> 預處理,編譯,匯編,連接
4.編譯有執行緒的檔案要加( )引數,
-lpthread
5.父行程等待子行程的結束,可以使用的函式是( )和( ),
wait( ) waitpid( )
6.linux 主要有兩個信號安裝函式,分別是
signal( ) , sigaction( )
7.Linux 作業系統內核由( )撰寫完成,
C 和匯編
8.目錄( )下存放 linux 作業系統啟動時所要用到的程式
/boot
9.Linux 中采用“一對一”的執行緒機制,也就是一個用戶執行緒對應一個( ), 內核執行緒
10.vim 三種模式:在命令模式下按下( )就進入了底線命令模式,
:
11.linux 檔案系統由四部分組成,( )用于存放檔案的控制資訊,
超級塊
12.執行緒本身呼叫( )函式可以退出執行緒,
> pthread_exit()
13.向訊息佇列發送訊息的函式是( ),
msgrcv()
14.( )系統呼叫可以根據檔案描述符來操作檔案特性,
stat()
15.Valgrind 包括很多工具,( )是 valgrind 應用最廣泛的工具,一個重量級的記憶體檢查器,能 夠發現開發中絕大多數記憶體錯誤使用情況,( )是主要用來檢查程式中快取使用出現的問題,
Memcheck,Cachegrind
16.信號發送函式中,( )用于設定定時器,當計時時間到達時,向行程發送 SIGALRM 信號,
setitimer()
加粗樣式17.當一個執行緒的屬性設定為( ),該執行緒結束時立即釋放它所占有的系統資源,
分離狀態
18.以下哪種方式屬于例外終止一個行程(D)
D.接到一個信號并終止,
19.下列命令哪個是創建執行緒私有資料命令(A)
A.pthread_key_create()
20.下面哪種通信方式適用于不同機器之間的行程通信,
(D ) 套接字
21.創建或打開訊息佇列的函式為(A )
msgget()
22.linux 中通過呼叫 waitpid()函式得到行程的退出資訊,該函式原型為 pid_t waitpid(pit_t pid, int *statloc, int options);當第一個引數 pid 取值為-1 時,表示(A) A 等待任一子行程退出,相當于
wait(),
23.Linux 環境中使用 kill 函式向行程或行程組發送信號,Kill 函式原型為 int kill(pid_t pid, int signo);當第一個引數 pid>0 時,表示( A )
A 發送信號給行程 ID 為 pid 的行程;
24.共享主存基本操作( A )將共享主存區映射到行程虛擬地址空間,
A shmat()
25.修改訊息佇列狀態資訊的命令是(B)
B msgctl()
26.使用 gdb 除錯程式時,next 和 step 命令的作用?( )
> 統呼叫的函式原型 next:單步運行,不進入函式內部; setp:單步運行,進入函式內部
27.Linux 系統的設備檔案分為三類?( )
> 字符設備檔案、塊設備檔案和網路設備檔案
28.標準 I/O 提供了三種型別的緩沖,分別是?( )
> 全緩沖,行緩沖,不帶緩沖
- 一個完整的信號生命周期包含 4 個重要的事件,這 4 個重要事件分別是?( )
> 信號誕生 信號在行程中注冊 信號在行程中注銷 信號處理函式執行完畢
30.互斥鎖只有兩種狀態,即?( ) 開鎖和上鎖
31.在標準 IO 庫中,rewind 函式作用?( ) 將檔案流指標指向檔案起始位置
32.c 語言中沒有明確給定初值的全域變數和靜態變數存放在哪兒?( )
> 未初始化資料區
33.函式 geteuid()用于得到行程的?( )
> 用戶有效 UID
34.一個行程是 ( )
> C、PCB 結構與程式和資料的組合,
35.一個行程呼叫 wait 或 waitpid 函式,可能產生 3 中情況,下列不屬于這 3 種 情況的是 ( ), 、
> D、如果該行程沒有子行程,立即回傳,回傳值為 0,
36.回傳呼叫行程的行程標識號的系統函式是 ( ),
A、 getpid
37.程式和行程是兩個不同的概念,以下不能描述這個觀點的是 ( ),
B、同一個程式運行 10 次,產生的是同一個行程
38.fork 函式在父行程中的回傳值是 ( ),
A、創建的子行程的行程標識號
39.在 Linux 中,下列不屬于正常結束行程的方法是 ( ),
D、呼叫 abort 函式,
40.以下程式的輸出結果是( )
******B、===================start of file
—parent my child is 4759,my pid is 4758,myparent pid is 3700
—child,my pid is 4759,my parent pid is 4758
===================end of file
===================end of file
41.以下程式輸出結果是( )
C、parent, var = 288 child, var = 100
------------finish---------------
------------finish---------------******
42.以下程式輸出結果是( )
**A、child, p = 7000, var = 1000 parent, p = 0, var = 100
43.哪種行程之間的通信,資料不可以重復讀( ) B、fifo C、管道
44.下述是 Linux 下多執行緒編程常用的 pthread 庫提供的函式名和意義,說法不正確的是?( )
D、pthread_exit 殺死一個執行緒
45.對執行緒函式來說,說法正確的是( ):
> A、pthread_create 中引數 arg 是傳遞給 start_routine 函式的引數
46.對互斥鎖及條件變數說法不正確的是( ):
> D、在使用條件變數時,互斥鎖會失去作用,所以是否有互斥鎖關系不重要
47.以下說明正確的是( ):
> B、執行緒是一個獨立的指令流,是在行程中被創建的,隨行程的關閉而關閉
48.執行緒 A SendMessage 給執行緒 B,執行緒 B 處理該訊息時又 SendMessage 給執行緒 A,會出現 ( ):
> B、繼承執行
48.linux 檔案系統通常由四部分組成:引導塊,超級塊,索引節點和( ), B、資料塊
49.任何行程在運行時默認打開的三個流物件,都有相應的檔案描述符,標準檔案描述符定 義標準輸入設備的值為( ), A、0
50.系統呼叫的函式原型 int open(const char *pathname, int flags),flag 值中( )表示以讀寫的 方式打開檔案
, *C、O_RDWR 51 系統呼叫的函式原型 int open(const char pathname, int flags),flag 值中( )表示若檔案 存在且為只讀或只寫成功打開,則將長度截為 0, B、O_TRUNC 52此行代碼
length=lseek(fd,0,SEEK_END);中的 length 的值表示( ),
A、檔案 lseek.txt 的大小
53.使用下列函式呼叫 int fcntl(int fd, int cmd);來實作檔案描述符的復制,cmd 引數應使用哪 一個?
A、F_DUPFD
54.閱讀程式填空:如果想要獲取檔案的大小,空白處應該填寫以下哪個答案, A、 statBuf.st_size
55.在創建檔案和目錄時候,有默認權限,如果 umask 值為 0022,則檔案的默認權限為( ) B、0644
56.執行程式,代碼輸出結果為( ), A.link num:2
57.獲取目錄的系統呼叫函式為( ) , B、getcwd()
填空
- gcc 編譯程序:預處理、編譯、匯編、連接, Jdb:b:設定斷點;r:執行程式;c:執行下面的程式 Vim:nyy:賦值 n 行;ndd:洗掉 n 行;p 或 P:粘貼在游標所在行的下一行或者上一 行,
- 行程初始化資料區:全域初始化資料區/靜態資料區, 行程的運行環境:代碼區、初始化資料區、未初始化資料區、堆區、 堆疊區
- 行程的堆區:用于動態記憶體分配,一般由程式員分配和釋放,若程式員不釋放,程式結 束時由 OS 回收,
- Linux 檔案系統中的塊有(根據塊使用的不同):引導塊、超級塊、Inode 塊、資料塊, 控制資訊、檔案基本屬性等是 Inode 節點,為檔案系統索引,存放資料的為資料塊,超 級塊中含有檔案系統的基本資訊,如塊大小、指向空間 inode 和資料塊的指標等相關信 息,
- 行程運行時默認打開的標準物件:標準輸入設備 stdin、標準輸出設備 stdout、標準錯誤 輸出設備 stderr,
- 軟連接和硬鏈接的特點:硬鏈接和原來的檔案公用一個 Inode 節點,相當于加了個相同 的檔案,只是改了改名字, 硬鏈接創建函式:link 洗掉硬鏈接函式:unlink 軟連接創建函式:symlink
讀取軟連接中的內容所用的函式:readlink(檔案名,讀取到的空間,讀取的大小),
- 修改文
件權限命令:chmod、chgrp、chown,
- 檔案描述符為整形:對于用戶空間來說,任何打開的檔案都將分配一個唯一非負整數, 用于標識該打開檔案,該值即檔案描述符,為一個大于等于 0 的整數,
- 權限的值,讀:4 寫:2 執行:1 注意:前三位為用戶的權限,再三位為所屬組的權 限,再三位為其他用戶的權限,
- 獲取檔案屬性,是否穿透,stat 函式具有穿透能力,能夠穿透鏈接檔案;而 lstat 函式不 具有穿透能力,不穿透鏈接檔案,檔案型別還為鏈接檔案,
- opendir 函式:打開一個目錄,回傳一個目錄流指標,引數為欲打開目錄的名稱(路徑), mkdir 函式:第一個引數時欲創建的目錄檔案路徑,第二個引數時創建目錄的權限,
- wait 函式:呼叫 wait 函式的父親行程將堵塞式等待改進的任意一個子行程結束后,回收 該子行程的內核行程資源,引數用來接受子行程退出狀態,回傳值為子行程的 PID, waitpid 函式,用來等待指定子行程結束,回傳值為子行程的 PID, 第一個引數,大于 0 時,表示等待行程 PID 為該 PID 值的行程結束; 等于 0 時,表示等待與當前行程的行程組 PGID 一致的行程結束; 等于-1 時,與 wait 函式相同; 小于-1 時,表示等待行程組 PGID 是此值的絕對值的行程結束, 第二個引數用來接受等待行程的結束狀態,第三個引數一般設定為,
- fork 函式:創建行程,
- 行程的行程塊沒有被釋放,稱為行程的僵死狀態,
- Fcntl 函式:修改某個檔案描述符的特殊屬性
- 創建硬鏈接的系統呼叫:link()
- 安裝信號處理函式:signal 和 sigaction,
- 信號的生命周期:在目的行程中安裝信號;行程產生信號;信號在目的行程中被注冊(目的行程收到信號); 信號在行程中被注銷(在執行相應處理函式之前);信號生命終止(執行完回應處理函式后 再恢復到被中斷的位置繼續執行),
- 訊息佇列中發送資訊的函式:msgsnd
- 信號是在軟體層次上對中斷機制的一種模擬,是一種異步通信方式,
- 接受訊息佇列的函式 msgrcv
- alarm()設定定時器
- 信號分為可靠信號和不可靠信號,
- 管道分為有名管道和匿名管道,
- 互斥鎖的兩種狀態:上鎖和解鎖,
- 自己退出執行緒的函式:pthread_exit() 被取消執行緒運行:pthread_cancle()
- 互斥鎖、條件變數、讀寫鎖的初始化 互斥鎖的初始化:pthread_mutex_init() 條件變數的初始化:pthread_cond_init() 讀寫鎖的初始化:pthread_rwlock_init()
- 讀寫鎖:非阻塞的加鎖解鎖和阻塞的加鎖解鎖, 堵塞的方式申請讀鎖:pthread_rwlock_rdlock() 非堵塞的方式申請讀鎖:pthread_rwlock_tryrdlock() 堵塞方式申請寫鎖:pthread_rwlock_wrlock()
非堵塞方式申請寫鎖:pthread_rwlock_trywrlock()
- 執行緒編譯的時候加上-lpthread,
- 回收執行緒的函式:pthread_join()
- 互斥鎖的上鎖函式是 pthread_mutex_lock(),非阻塞加 try; 解鎖函式是 pthread_mutex_unlock(),
- 面向連接的編程:TCP;面向無連接的是:UDP
- 在不同主機間進行通訊的是:scoket 或者是套接字
- TCP 和 UDP 都是傳輸層的協議,
- 三次握手:連接建立、資料傳輸、連接釋放,
- 創建套接字的函式 scoket()
- 網路編程的常見函式
監聽網路函式:listen() 發起連接函式:connect()
接受連接函式:accept() 讀寫 scoket 物件:read()/write()
TCP 發送和接受資料:send()/recv() 關閉 scoket物件:close()
簡答題
1.簡述一下系統呼叫和庫函式 舉例說明
庫函式:由系統提供,用戶無須定義,也不必在程式中作型別說明,只需在程式前包含有該函式 原型的頭檔案即可在程式中直接呼叫 如使用 printf
return 系統呼叫:作業系統的一部分;用戶應用程式訪問并使用內核所提供的各種服務的途徑即是系 統呼叫,如 exit
2.open 系統呼叫的打開標志 只讀:O_RDONLY 只寫:O_WRONLY 讀寫:O_RDWR 寫入時添加至檔案末尾:O_APPEND 不存在時創建:O_CREAT 截斷檔案為零長度:O_TRUNC
- vfs 虛擬檔案系統 虛擬檔案系統(Virtual File System, 簡稱 VFS), 是 Linux 內核中的一個軟體層,用于給用 戶空間的程式提供檔案系統介面;同時,它也提供了內核中的一個 抽象功能,允許不同的 檔案系統共存,系統中所有的檔案系統不但依賴 VFS 共存,而且也依靠 VFS 協同作業,
- VFS 是什么 VFS 的作用就是采用標準的 Unix 系統呼叫讀寫位于不同物理介質上的不同檔案系統,即 為 各類檔案系統提供了一個統一的操作界面和應用編程介面,VFS 是一個可以讓 open()、read()、
write()等系統呼叫不用關心底層的存盤介質和檔案系統型別就可以作業的粘合層,
- linux 檔案型別 普通檔案、目錄檔案、管道檔案、字符設備檔案、軟鏈接檔案、塊檔案、套接字檔案
- 什么是行程,行程資源由哪兩個組成 行程是計算機中程式的一次資料集合運算的活動,是系統進行調度和分配的基本單元,是操 作系統的基礎 行程資源由內核空間行程資源 用戶空間行程資源
- 行程結構 一個正在運行著的行程在記憶體空間中申請的代碼區、初始化資料區、未初始化資料區、堆區、 堆疊區 5 個部分,
- 程式與行程的區別 動態和靜態的區別:行程是程式及其資料在計算機上的一次運行活動,是一個動態的概念, 而程式是一組有序的指令集和,是一種靜態的概念 生命周期的區別:行程是程式的一次執行程序,他是動態創建和消亡的,程式是一組代碼的
集合,他是永久存在的 組成的區別:行程由程式 資料和 PCB 三部分組成,程式是一組有序的集合指令
9.fork 回傳值的意義 如果執行成功,在父行程中將回傳子行程的 PID,型別為 pid_t,子行程將回傳 0,以區別父 子行程, 如果執行失敗,則在父行程中回傳-1,錯誤原因存盤在 errno 中,
10.return 和 exit 的區別: return 是語言級別的,它表示了呼叫堆疊的回傳;而 exit 是系統呼叫級別的,它表示一個進 程的結束, 在 main 函式里,return(0)和 exit(0)是一樣的,子函式用 return 回傳,而子行程用 exit 退出,
呼叫 exit 時要呼叫一段終止處理程式,然后關閉所有 I/O 流
- 什么是孤兒行程 誰負責回收孤兒行程 孤兒行程就是其在正常運行時,父行程已經結束,導致其內核資源無法被父行程回收,孤兒 行程在父行程結束時將會把父行程設定為 init 行程,init 會對孤兒行程的資源進行回收處理
12.僵尸行程是什么,誰消滅 僵尸行程:行程已經退出,但它的父親行程還沒有回收內核資源的行程,即該行程在內核空 間的 PCB 沒有釋放,利用 kill 函式殺死父行程,僵尸行程會變成孤兒行程被 init 行程收養,
- fork 和 vfork 的區別與聯系 區別: fork()用于創建一個新行程,由 fork()創建的子行程是父行程的副本,即子行程獲取 父行程 資料空間,堆和 堆疊的副本,父子行程之間不共享這些存盤空間的部分,而
vfork()創建的進 程并不將父行程的地址空間完全復制到子行程中,因為子行程會立即呼叫 exec (或 exit)
于是也就不會存放該地址空間,相反,在子行程呼叫 exec 或 exit 之前,它在父 行程的 空間進行, vfork()與
fork()另一個區別就是:vfork 保證子行程先運行,在它呼叫 exec 或 exit 之 后 父行程才可能被調度運行, 相同:
兩者被呼叫一次,但是回傳兩次,兩次回傳的唯一區別是子行程的回傳值是 0,而 父行程 的回傳值則是新子行程的行程 ID,
14.父行程呼叫 wait 能出現的三種情況 當子行程都在執行時,wait 會使父行程進入阻塞狀態 當恰好有子行程結束時,wait 會回收子行程資源并且獲得子行程結束狀態 當無子行程時 wait 會立刻回傳-1 并且顯示報錯資訊
15.簡述可靠信號和不可靠信號的處理程序: 如果行程在屏蔽某個信號的時間內,其他行程多次向其發送同一個信號,不可靠信號只有一 次未決記錄,當行程解除屏蔽后,該信號只會被捕捉一次;而可靠信號作業系統會記錄所有 的發送,當行程解除屏蔽后,作業系統會捕捉對等次數,
16.簡單介紹一下信號的定義及其分類, 信號是表示訊息的物理量,是運載訊息的工具 信號是軟體中斷,是在軟體層次上對中斷機制的一種模擬,在原理上,一個行程收到一個信 號與處理器收到一個中斷請求可以說是一樣的
分類:確定信號和隨機信號;連續信號和離散信;周期信號和非周期信號;能量信號與功率 信號;因果信號與反因果信號;實信號與復信號
17.行程間通信方式: 信號,匿名管道,命名管道,信號量,共享記憶體,訊息佇列,套接字,Socket
- 請解釋一下有名管道和匿名管道的區別? 匿名管道是由 pipe 函式創建 并打開的 命名管道是由 mkfifo 函式創建 的 ,打開用 open 命名管道和匿名管道唯一的區別就是在創建的打開,一旦這些作業完成后,它們有相同的意 義
19.簡單介紹一下匿名管道及其特點 匿名管道是半雙工的,只有一個寫端和一個讀端 匿名管道不是普通的檔案,不是在磁盤上,而是在記憶體中的,所以它的生命周期隨行程的結 束而結束 匿名管道是基于位元組流來通信的
其本身有同步互斥的效果 匿名管道只能使用于有血緣關系的行程之間的通信
20.Please describe the difference of signal() and sigaction() in brief(描述一下 signal 和 sigaction 的區別與聯系英文題) 不同點:signal
只能呼叫信號處理函式,但是無妨向其輸入附帶的資料 sigaction 可以向信號處理函式傳遞資訊,并且可以設定信號掩碼,回傳設定之前的
sigaction 相同點:都可以為信號設定信號處理函式 共用了同一個內核函式 do_sigaction
21.信號處理方式 忽略此信號, 自定義捕捉信號函式, 執行系統默認操作,
- 信號產生的方式 當用戶按某些鍵時產生信號, 硬體例外產生信號, 終止行程信號, 軟體例外產生信號
23.信號的生命周期 在目的行程中安裝信號;行程產生信號;信號在目的行程中被注冊(目的行程收到信號); 信號在行程中被注銷(在執行相應處理函式之前);信號生命終止(執行完回應處理函式后 再恢復到被中斷的位置繼續執行),
24.簡述什么是執行緒及特點 執行緒就是系統運算執行的最小單位,其所占資源較少 執行緒是行程的一個執行序列 執行緒可以看作是輕量化的行程,執行緒之間的切換代價小
25.pthread_kill 函式和 pthread_cancle 函式的區別:(兩個都是終止行程的)pthread_kill 函式的功能是向指定執行緒發送信號,信號為 0 時用于檢查此執行緒 ID 的執行緒 是 否存活,pthread_cancel
函式的功能是給執行緒發送取消信號,使執行緒從取消點退出,
- pthread_exit()和 pthread_cancel()的區別 pthread_exit()是結束本執行緒 pthread_cancel()是結束其他執行緒
- 簡述互斥鎖與讀寫鎖的區別與聯系, 區別:讀寫鎖區分讀者和寫者,而互斥鎖不區分 互斥鎖同一時間只允許一個執行緒訪問該物件,無論讀寫;讀寫鎖同一時間內只允許一個寫者, 但是允許多個讀者同時讀物件,
聯系:讀寫鎖在獲取寫鎖的時候機制類似于互斥鎖,
28.條件變數中 pthread_cond_wait 實作的步驟 解鎖 判斷條件是否成立 如果成立則上鎖執行,不成立將進入阻塞狀態
- 執行緒與行程的區別 行程是資源分配的最小單位,執行緒是程式執行的最小單位, 行程有自己的獨立地址空間,每啟動一個行程,系統就會為它分配地址空間,建立資料表來維護代碼段、堆疊段和資料段,而執行緒是共享行程中的資料的,使用相同的地址 空 間,因此 CPU
切換一個執行緒的花費遠比行程要小很多,同時創建一個執行緒的開銷也 比 行程要小很多,
執行緒之間的通信更方便,同一行程下的執行緒共享全域變數、靜態變數等資料,而行程 之 間的通信需要以通信的方式進行,
多行程程式更健壯,多執行緒程式只要有一個執行緒死掉,整個行程也死掉了,而一個進 程死掉并不會對另外一個行程造成影響,因為行程有自己獨立的地址空間,
- tcp 和 udp 的區別 TCP 需要連接,UDP 是無連接的,發送資料之前不需要建立連接 TCP 提供可靠的服務,通過 TCP 連接傳送的資料,無差錯,不丟失 TCP 邏輯通信信道是全雙工的可靠信道,UDP 則是不可靠信道
- TCP 的三次握手 第一次握手 客戶主動(active open)去 connect 服務器,并且發送 SYN 假設序列號為 J, 服務器是被動打開(passive open) 第二次握手 服務器在收到 SYN 后,它會發送一個 SYN 以及一個 ACK(應答)給客戶,ACK 的序列號是 J+1 表示是給 SYN J 的應答,新發送的 SYN K 序列號是 K 第三次握手 客戶在收到新 SYN K, ACK
J+1 后,也回應 ACK K+1 以表示收到了, 然后兩邊就可以開始資料發送資料了
- osi 七層模型 應用層 表示層 會話層 傳輸層 網路層 資料鏈路層 物理層
33.使用 gdb 除錯程式時,next 和 step 命令的作用? next:單步運行,不進入函式內部; setp:單步運行,進入函式內部
34.Linux 系統的設備檔案分為三類? 字符設備檔案、塊設備檔案和網路設備檔案
35.標準 I/O 提供了三種型別的緩沖,分別是? 全緩沖,行緩沖,不帶緩沖
- 一個完整的信號生命周期包含 4 個重要的事件,這 4 個重要事件分別是? 信號誕生 信號在行程中注冊 信號在行程中注銷 信號處理函式執行完畢
37.互斥鎖只有兩種狀態,即? 開鎖和上鎖
38.在標準 IO 庫中,rewind 函式作用? 將檔案流指標指向檔案起始位置
39.c 語言中沒有明確給定初值的全域變數和靜態變數存放在哪兒? 未初始化資料區
40.函式 geteuid()用于得到行程的? 用戶有效 UID
編程題
1.創建檔案 file1,寫入字串“abcdefghijklmn”; 創建檔案 file2,寫入字串“ABCDEFGHIJKLMN”; 讀取file1中的內容,寫入file2,使file2中的字串內容為“abcdefghijklmn ABCDEFGHIJKLMN”
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
int main()
{
int fd1,fd2;
char str[14];
fd1 = open("file1",O_RDWR|O_CREAT,S_IRWXU);
if(fd1 < 0)
perror("open");
write(fd1,"abcdefghijklmn",14);
lseek(fd1,0,SEEK_SET);
fd2 = open("file2",O_RDWR|O_CREAT,S_IRWXU);
if(fd2 < 0)
perror("open");
lseek(fd2,14,SEEK_END);
write(fd2,"ABCDEFGHIJKLMN",14);
read(fd1,str,14);
lseek(fd2,0,SEEK_SET);
write(fd2,str,14);
close(fd1);
close(fd2);
system("cat file2");
printf("\n");
return 0; }
> 2.創建新檔案,該檔案具有用戶讀寫權限, 采用 dup/dup2/fcntl 復制一個新的檔案描述符,通過新檔案描述符向檔案寫入“class_name” 字串;通過原有的檔案描述符讀取檔案中的內容,并且列印顯示
```c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
int fd,fd1;
char *str = "class_name";
fd = open("file",O_CREAT|O_RDWR);
if(fd < 0)
perror("open");
fd1 = dup(fd);
if(fd1 < 0)
perror("dup");
write(fd1,str,strlen(str));
lseek(fd,0,SEEK_SET);
char buf[12];
read(fd,buf,12);
printf("The buf is:%s\n",buf);
close(fd);
close(fd1);
return 0; }
3.遞回遍歷/home 目錄,列印出所有檔案和子目錄名稱及節點號, 判斷檔案型別,如果是子目錄,繼續進行遞回遍歷,直到遍歷完所有子目錄為止,
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
void show(char *path)
{
DIR *dir;
char str[128];
struct dirent *dirp;
struct stat statbuf;
dir = opendir(path);
if(dir)
{
while((dirp = readdir(dir)) != NULL) {
sprintf(str,"%s/%s",path,dirp->d_name);
if(lstat(str,&statbuf) < 0)
perror("lstat");
if(dirp->d_name[0] == '.')
continue;
if(S_ISDIR(statbuf.st_mode))
{
show(str);
printf("The dirent's name is: %s\n",dirp->d_name);
printf("The dirent's inode is: %d\n",dirp->d_ino);
}
else
{
printf("The file's name is: %s\n",dirp->d_name);
printf("The file's inode is: %d\n",dirp->d_ino);
} } }
else
perror("opendir");
closedir(dir);
}
int main()
{
show("/home");
return 0; }
4.列印字串“hello world!” 在列印字串“hello world!”前呼叫三次 fork,分析列印結果,
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
fork();
fork();
fork();
printf("hello world!!!\n");
return 0 }
5.創建子行程 在子行程中打開檔案 file1,寫入自己的“班級_姓名_學號”, 父行程讀取 file1 中的內容,并且列印顯示, 在父行程中獲取已經結束的子行程的狀態資訊,列印該資訊,并且列印結束的子行程的行程 號,
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
int main()
{
int fd,pid;
fd = open("file",O_CREAT|O_RDWR,S_IRWXU);
if(fd< 0)
perror("open");
pid = fork();
if(pid == 0)
{
printf("This is the child!\n");
char str[128] = "移動二班_段振威_1915925158";
if(write(fd,str,128) < 0)
perror("write");
exit(5);
}
else
{
printf("This is the father!\n");
char buf[128];
int n,status;
if(read(fd,buf,128) < 0)
perror("read");
printf("The buf is: %s\n",buf);
if(wait(&status) < 0)
perror("perror");
if(WIFEXITED(status))
n = WEXITSTATUS(status);
else
printf("wait error!\n");
printf("The child's pid is: %d\n",pid);
printf("The child exit status is: %d\n",n);
}
return 0;
}
6.在父行程中定義變數 n,在子行程中對變數 n 進行++操作;并且列印變數 n 的值,列印子 行程 pid; 在父行程中列印變數 n 的值,并且列印父行程 pid, 要求分別用 fork 和 vfork 創建子行程,
//------fork
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
int n = 1;
if(fork() == 0)
{
printf("This is child,the pid is%d\n",getpid());
printf("The n is: %d\n",++n);
}
else
{
printf("This is father,the pid is%d\n",getpid());
printf("The n is: %d\n",n);
}
return 0;
}//-----vfork
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int n = 1;
pid_t pid;
pid = vfork();
if(pid < 0)
perror("vfork");
else if(pid == 0)
{
printf("This is child,the child's pid is: %d\n",getpid());
printf("The n is: %d\n",++n);
exit(0);
}
else
{
printf("This is father,the father's pid is: %d\n",getpid());
printf("The n is: %d\n",n);
}
return 0;
}
7.利用匿名管道實作父子行程間通信,要求 父行程發送字串“hello child”給子行程; 子行程收到父行程發送的資料后,給父行程回復“hello farther”; 父子行程通信完畢,父行程依次列印子行程的退出狀態以及子行程的
pid,
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
int fd1[2],fd2[2];
pipe(fd1);
pipe(fd2);
int pid;
pid = fork();
if(pid < 0)
perror("fork");
else if(pid == 0)
{
close(fd1[0]);
close(fd2[1]);
char str[12];
printf("This is the child!\n");
if(read(fd2[0],str,12) > 0)
{
printf("Received the news: %s\n",str);
if(write(fd1[1],"hello father",12) < 0)
perror("write");
}
else
perror("read");
exit(5);
}
else
{
int status;
printf("This is the father!\n");
close(fd1[1]);
close(fd2[0]);
char buf[24] = "hello child";
if(write(fd2[1],buf,12) < 0)
perror("write");
else
{
printf("Send news successful!\n");
}
wait(&status);
if(WIFEXITED(status))
{
printf("The child's pid is: %d\n",pid);
printf("The child's exited status is: %d\n",WEXITSTATUS(status));
} }
return 0;
}
- 利用匿名管道實作兄弟行程間通信,要求 兄行程發送字串“This is elder brother ,pid is (兄行程行程號)”給第行程; 第行程收到兄行程發送的資料后,給兄行程回復“This is younger brother ,pid
is(第行程進 程號)”;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
int main()
{
int fd1[2],fd2[2];
pipe(fd1);
pipe(fd2);
int pid;
pid = fork();
if(pid == 0)
{
printf("This is the elder brother!\n");
printf("The elder's father's pid is: %d\n",getppid());
close(fd1[1]);
close(fd2[0]);
char str1[64],str2[64];
sprintf(str1,"This is the elder brother,pid is %d",getpid());
if(write(fd2[1],str1,64) < 0)
perror("write");
if(read(fd1[0],str2,64) < 0)
perror("read");
else
printf("The news from younger is: %s\n",str2);
}
else
{
if(fork() == 0)
{
printf("This is the younger brother!\n");
printf("The younger's father's pid is: %d\n",getppid());
close(fd1[0]);
close(fd2[1]);
char buf1[64],buf2[64];
if(read(fd2[0],buf1,64) > 0)
{
printf("The news form elder is: %s\n",buf1);
sprintf(buf2,"This is the younger brother,pid is %d",getpid());
if(write(fd1[1],buf2,64) < 0)
perror("write");
}
else
perror("read");
} } }
- 利用有名管道檔案實作行程間通信,要求 寫行程向有名管道檔案寫入 10 次“hello world”; 讀行程讀取有名管道檔案中的內容,并依次列印
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main()
{
int pid,fd;
if(mkfifo("fifotest",0666) < 0)
perror("mkfifo");
pid = fork();
if(pid < 0)
perror("fork");
else if(pid == 0)
{
printf("This is the write process!\n");
int fd = open("fifotest",0666);
for(int i = 0; i < 10;i++)
{
if(write(fd,"hello world",12) < 0)
perror("write");
sleep(1);
}
close(fd);
}
else
{
char str[128];
printf("This is the read process!\n");
int fd1 = open("fifotest",0666);
for(int i = 0;i < 10;i++)
{
if(read(fd1,str,128) < 0)
perror("read");
else
printf("%s\n",str);
}
system("rm -f fifotest");
} }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/389554.html
標籤:其他
