linux C學習第二天之應用編程和網絡編程筆記(上)

1、C語言中不能再一個函數裏面定義別的函數  。所以沒有局部函數

2、const int a=5;   int const a=5;  兩者意義一樣 該變量a的值是個常量,不能改變

  const int *p;  

 int const *p ; 

const 在*前面表示指向的數據是個常量,指針可以改變

int * const p;

const int *const p;

const 在*後面的表示指向的指針是個常量,值不一定是個常量

一、文件描述符 :出了當前進程就沒有意義了

   1、關於man命令的使用

    man 1 xxx  查shell命令 

  man 2 xxx 查API

man 3 xxx查庫函數


2、我們如何退出程序

  (1)在main中return  如果程序正常運行,正常返回 return 0,如果異常退出 則return -1;

 (2)   (1)不算是比較常規的退出進程方法  ,正式終止進程  應該使用 exit()  _exit()    _Exit()

 

關於exit()和_exit()

  exit()函數定義在stdlib.h中,而_exit()定義在unistd.h中


簡單的說,exit函數將終止調用進程。在退出程序之前,所有文件關閉,緩衝輸出內容將刷新定義

_exit終止調用進程,但不關閉文件,不清除輸出緩存,也不調用出口函數


3、阻塞與非阻塞(關於open時候的flag  O_NONBLOCK)

  (1)如果一個函數是阻塞的,則我們調用這個函數時進程有可能被卡住(阻塞住,實質是該函數執行的條件未成熟,沒法執行,得等待時機成熟)

  (2)如果一個函數是非阻塞的,我們調用該函數時,該函數會立即返回,但是否完成任務不一定。

    (3)阻塞與非阻塞是兩種不同的設計思路,並沒有好壞。總的來說,阻塞式的結果有保障,但時間沒保障。非阻塞式的時間有保障但結果沒保障。

(4)操作系統的API或者由API封裝成的庫函數 有很多本身就是被設計爲阻塞式或者非阻塞式的。所以我們應用程序調用這些函數時一定要非常清楚。

(5)我們打開文件的時候默認的是阻塞式的,如果你希望以非阻塞的方式打開文件,則flag中要加O_NONBLOCK方式打開文件。

(6)阻塞與非阻塞只用於設備文件,不用與普通文件

4、O_SYNC

  (1)WRITE 阻塞等待底層將緩衝區數據寫回硬盤 才返回應用層

 (2)無O_SYNC時 只是將內容寫進緩衝區即返回。。



(二)、文件讀寫的一些細節

   1、errno   其實就是error number linux操作系統給各種常見錯誤編號,當函數執行錯誤時,函數會返回一個特定的錯誤編號errno 告訴我們到底哪裏錯了。

 2、errno 是OS維護的一個全局變量,任何OS內部函數都可以通過設置errno來告訴上層調用者究竟發生了一個什麼錯誤。

3、errno本身是一個int類型的數字,比如-37,每個不同的錯誤號對應一個錯誤信息,linux系統提供了一個函數perror  來輸出錯誤信息。錯誤信息不用我們提供,直接在出錯位置perror("打開文件錯誤"); //perror()裏面是一個字符串


(三)、read和write的 count 參數 

  1、count  是我們想要讀或者寫的字節數目 

    返回值是實際完成的我們要寫的或者讀的字節數,可能等於要讀寫的字節數或者小於(未完成)

2、當讀寫和阻塞非阻塞聯合事情就更復雜了。 如果一個函數是阻塞的,我們要讀30字節,目前只有20個字節,則讀取20個字節時就會阻塞等待剩餘的10個字節。

3、要讀寫的文件很大的時候 應該設置一個合適的一次讀寫的count數目,循環讀寫 而不應該一次性讀寫完

(四)、文件IO效率和標準IO

   1、文件IO是指當前所說的open write read 等 API 函數構成的一套用來讀寫文件的體系 這套體系可疑很好的讀寫文件但是效率有些低。

  2、應用層C語言庫提供了一些用來讀寫文件的函數列表,叫做標準IO,標準IO 由一系列的庫函數構成,(f_open,f_close,f_read,f_write),這些標準IO其實是由文件IO封裝而成的,(比如f_open內部還是調用了open.)標準IO加了封裝主要是爲了在應用層增加一個緩衝機制,這樣我們通過f_write函數寫的內容並不是直接進入內核buf中,而是先進入應用層標準IO庫維護的buf中,然後標準IO根據操作系統單詞write的最佳count選擇最佳的時機來完成write到內核buf中(內核再根據最好的時機去將buf數據寫到磁盤上)


(五)linux如何管理文件

   1、快速格式化和底層格式化 :

    快速格式化:速度很快 ,比如格式化一個32G硬盤只需要1秒   底層格式化比較慢

  兩者的差別:快速格式化只是刪除了inode信息,並沒有刪除數據,有可能還原格式化後的硬盤。 底層格式化則是將數據刪除了,基本上是不可能還原數據的。

2、文件與流

     (1)流(stream)  文件讀出或者寫入時只能一個字符一個字符的操作,這樣就夠成了一個流。

(2)流這個概念是動態的,不是靜態的

(3)編程中提到的流是與IO相關的,所以叫IO流。文件操作時就構成一個IO流。

3、lseek

  當打開一個空文件時,默認情況是文件指針指向文件流開始,所以這時候去write是從文件開頭寫的。

 write 和 read函數值自帶移動文件指針。如果讀寫NGe字節,則文件指針後移N個字節

如果想要隨意移動文件指針 則需使用lseek

  *****當調用lseek移動文件指針之後,再去調用read和write函數則從移動後的文件指針開始。

4、stdin stdout stderr 對應描述符是0 ,1 , 2標準輸入 標準輸出 標準錯誤

   printf 默認輸出到標準輸出   fprintf則可以指定輸出到那個文件描述符中

 int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);


(六)文件共享的問題

1、文件多次打開


     普通文件可以被重複打開  重複打開一個相同的文件。兩個不同的fd,對其讀寫 是分別讀和分別寫

如果希望是接續寫讀  則 在open時候flag 時候|O_APPEND   爲什麼加O_APPEND就可以接續寫呢 關鍵核心是文件指針

 http://edu.csdn.net/course/detail/2401/37561?auto_start=1      第九課   文件重複打開

2、何爲文件共享

     (1)文件共享就是,同一個文件(同一個文件即同一個inode,相同的路徑名)被多個獨立的讀寫體(可以理解爲多個文件描述符)去同時(一個文件打開但是尚未關閉就去執行另一個操作)操作。

  (2)文件共享的意義有很多:比如我們可以通過多線程同時去操作一個大文件,提高讀寫效率。

3、文件共享的核心是如何弄出來多個文件描述符指向同一個文件

   常見的方法有三種:(1)同一個進程多次使用open打開同一個文件(fd不相同)。。(2)是在不同的進程中去使用open打開同一個文件(兩個進程的fd有可能相同有可能不同) (3)linux 內核提供了一個API   dup()和 dup2()讓進程複製文件描述符(dup複製文件描述符,但是賦值出來的fd2是與fd1不同的,只是複製了一份fd1d的描述符表。所以兩個fd對應的相同的文件指針,因此dup 和dup2其實只能接續讀寫)

  我們關注文件共享時是關心文件讀寫是分別讀寫還是接續寫


*************父進程創建的子進程退出後,父進程沒有回收子進程的結束信息時,子進程就便成一個殭屍進程,因此檔一個父進程調用fork函數創建一個子進程而不調用wait函數時,一個殭屍進程就誕生了。

***************當父進程在子進程之前結束運行,這時該子進程就成爲孤兒進程,linux系統由init進程負責領養所有的孤兒進程






發佈了41 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章