Linux開發環境及其應用 《第14周單元測驗》及其解析

1、使用MemoryMap方式訪問磁盤文件,不需要事先用open()系統調用打開文件。由於每個進程可以打開的文件總數是有限的,所以這種文件訪問方式可以節約進程的文件描述符資源。

×

查看一下系統調用mmap()的參數,有fd。在Linux內核程序中,open()調用非常複雜,代碼量比read()/write()要大得多,除了把i節點之類調入內存完成文件邏輯塊與磁盤塊之間的映射之外,另外一個重要功能就是完成對文件訪問權限的判斷處理。所以,即使不用read()、write()機制訪問文件,而只是mmap()機制訪問文件,留用open的這些安全功能也是有意義的,可以簡化系統設計。

2、兩個獨立的可執行程序a和b,程序運行時,兩者通過MemoryMap方式同時訪問一個磁盤文件同一位置的數據。這樣,不需要通過IPC“共享內存”機制中的semget()和semat()等系統調用也可以實現兩獨立進程通過共享內存通信,而且,進程無論正常或者異常終止,都可以做到將修改過的數據自動持久化存儲到磁盤文件中。

有的同學的程序存在這樣的問題,打開文件後訪問文件,不執行close()程序就直接退出。回想一下我們之前介紹的三級的“活動文件目錄”,程序退出時,操作系統可以知道進程打開過哪些文件,自動關閉它。如果你的程序是長期運行,訪問過的文件不關閉,再打開新的文件,會導致文件描述符資源耗盡,就如同殭屍進程佔盡進程槽而無法創建新進程一樣,新文件無法打開。正常情況,文件訪問完畢,執行munmap()調用,再執行close(),但進程異常終止,通過進程頁表找到相關頁面,可以完成munmap()的功能,文件也一樣會被自動close(),執行文件關閉的操作。

3、使用cat打印出一個有100行數據的文本文件,但只能顯示出前50行,後50行被阻塞而遲遲不能顯示。出現這種現象的一種可能原因是:其他某進程使用fcntl()系統調用將這個文件的後50行數據上了“寫鎖”,因爲寫鎖鎖定時不允許讀導致cat被阻塞,如果該進程上鎖類型是“讀鎖”,那麼,cat只是打開文件讀,將不會被阻塞。

×

這個題我也做錯了,讀題容易被題目帶到溝裏
fcntl執行的是“諮詢式鎖定”不是“強制性鎖定”,cat讀文件時直接read()並不做fcntl(),不做fcntl()就不會導致cat進程阻塞在“寫鎖”上

4、某程序僅使用read()/close()系統調用訪問文件,程序主流程爲

     fd = atoi(argv[1]);
      while ((n = read(fd, buf, sizeof buf)) > 0) { 
              ... 
      }
      close(fd);

程序被exec()系統調用加載前,以命令行參數方式傳遞一個已經事先打開好的文件描述符。這樣,無論fd引用的是磁盤文件,匿名管道,命名管道,終端設備文件,socket,程序均能正常工作。

這正是“一切皆文件”的設計思路帶來的好處。你若能開發一個特定虛擬設備, 通過fd = open("/dev/myMicroPhone", O_RDONLY);打開讀,你能把麥克風的語音輸入變成文本,那麼,上面的處理程序也不需要做任何改動。完美!

5、Linux設計得非常健壯,一直以運行穩定而著稱。當系統中多個進程因爲對信號量操作出現不恰當的P操作和V操作將導致死鎖時,semop()系統調用將直接返回-1,系統拒絕錯誤的操作,從而避免死鎖的發生。

×

策略與機制相分離

6、對信號量的P操作有可能導致進程進入阻塞狀態,也有可能不進入阻塞狀態,但是V操作確定不會導致當前進程進入阻塞狀態。

V操作要讓當前進程進入阻塞狀態,阻塞起來有什麼意義?等什麼事件?都不需要。所以,V操作不會導致當前進程阻塞,但可以想象,在內核代碼裏,會導致相關聯P操作的進程從“阻塞態”中解除。

7、UDP提供了不可靠數據報服務,但如果通信線路沒有任何誤碼和數據丟失,接收進程可以接收到發送進程發來的所有數據。

×

UDP沒有“流量控制機制”,所以,即使通信線路沒有任何差錯,也有可能接收緩衝區滿導致不得不丟棄數據,接收進程無法獲得發送方發出的這個數據

8、UDP提供了不可靠服務,所以通信線路誤碼導致的數據比特被翻轉會傳遞到UDP之上的應用層程序,因此對於一些重要的應用使用UDP通信應增加類似CRC等校驗機制。

×

鏈路層的校驗已經很強了,有線以太網和WiFi都提供了CRC32校驗,歷數所有鏈路層協議,只有已被淘汰的SLIP協議沒有校驗,其他全部有校驗。這個是協議體系結構中的安排,把強校驗放到鏈路層,因爲鏈路層一般是硬件實現的,硬件做校驗比CPU軟件實現開銷要小,就算軟件實現的PPP over serial line,也有軟件查表法計算CRC。所以,鏈路層可以發現(算然不見得有自動重傳來糾正誤碼)誤碼。退一步講,UDP自己也有校驗和。UDP校驗和是選項,校驗和域0,就是沒有校驗;校驗和非零,就採用了算術和校驗(這個CPU擅長,但CPU不擅長CRC),若湊巧算術和校驗是0,就在校驗域填寫-1。你可以WireShark看一下,你的UDP都有校驗和嗎?

9、TCP嚮應用程序提供了“可靠的面向連接的字節流”服務,因此,應用程序交付給TCP的數據總能準確地傳送到接收方,網絡丟包會導致自動超時重傳,網絡導致的數據亂序也被糾正。

×

這道題容易把人往溝裏帶,首先明確的是,TCP可靠的面向連接的字節流,數據總能準確的傳送給接收方。但是要記住的是,面向連接,發送的字節流就一定保證了有序,前面發送的字節流沒有獲得ack確認,那麼就不會在傳下一個包,即便使用了滑動窗口協議或者選擇重傳(允許前一個數據未確認就發下一數據),發送的數據也同樣是保持有序傳輸的。TCP會導致網絡丟包,但是不會導致數據亂序。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章