小程序分析(fork()和vfork())


  1. 分析下述程序,i<4時,最終創建了多少個進程。

    fork()是創建一個子進程。

wKioL1dr8FnyJVySAAA0rxzoUSc801.png

 分析:i=0時,父進程1創建了一個子進程1。(此時共2個進程)

       i=1時,父進程1繼續創建子進程2,將子進程1又當成父進程,創建子進程3。(此時共6個進程)

       i=2時,將子進程當成父進程繼續創建子進程。之前的父進程繼續創建子進程。(此時共14個進程)

       i=3時,將子進程繼續當成父進程繼續創建子進程。之前的父進程繼續創建子進程。(此時共30個進程)


wKioL1dr9uiC8Tl4AAAYowWUwf4718.png

注:可先計算由父進程創建的進程數,最後乘2即爲總進程數。

擴展:當i<10時,一共創建了2046個進程。


2. 分析爲什麼在vfork()創建一個子進程中,在子進程中不能用return。

   

wKioL1dsAdTBTeSlAAA4E_rKcvE421.png

wKiom1dsAdjR3GZ5AAAQV-7j6pU664.png

注:從結果可以看出:子進程先運行。在它調用execexit之後父進程纔可能被調度運行。


  若將程序中的exit(0)改爲return 0;將會出現錯誤。這是爲什麼呢?

  首先,先來分析下exit()和return的區別

  exit() 是退出整個程序,將控制權交給操作系統。在執行了exit()後,所有的內存和臨時存儲區會被刷新,所有文件會被關閉,控制權不再在程序中。

  return 是從函數返回,並將控制權交給調用函數。如果在main()中,可直接return 0,退出當前進程。若不在main()函數中,則是退出上一層調用。

  下面就解釋,爲什麼在vfork中不能用return

  vfork() 創建出來的子進程和父進程共享一個內存數據。子進程的main()函數 return掉了,將程序函數的棧發生了變化。當main()函數return後,會調用exit(),父進程收到子進程exit(),開始從vfork()返回,但是,父進程的棧被子進程給return掉了。棧返回一個棧地址,再次調用main(),進入了一個無限循環。


fork() 和 vfork() 的區別:

fork()和vfork()都是創建一個子進程。

區別:

(1)fork() :子進程拷貝父進程的數據段,代碼段

     vfork() :子進程與父進程共享數據段

(2)fork() :父子進程的執行順序不確定,有調度器決定

     vfork():保證子進程先運行,在調用execexit之前與父進程數據是共享的,在它調用execexit之                 後父進程纔可能被調度運行。


3. FILE結構體

  struct file結構體在include/linux/fs.h中定義。文件結構體代表一個打開的文件,系統中的每個打開的文件在內核空間都有一個關聯的 struct file。它由內核在打開文件時創建,並傳遞給在文件上進行操作的任何函數。在文件的所有實例都關閉後,內核釋放這個數據結構。在內核創建和驅動源碼中,struct file的指針通常被命名爲filefilp

  FILE結構體:

  struct file {
  union {
  struct list_head fu_list; 文件對象鏈表指針linux/include/linux/list.h
  struct rcu_head fu_rcuhead; RCU(Read-Copy Update)是Linux 2.6內核中新的鎖機制
  } f_u;
  struct path f_path; 包含dentry和mnt兩個成員,用於確定文件路徑
  #define f_dentry f_path.dentry f_path的成員之一,當前文件的dentry結構
  #define f_vfsmnt f_path.mnt 表示當前文件所在文件系統的掛載根目錄
  const struct file_operations *f_op; 與該文件相關聯的操作函數
  atomic_t f_count; 文件的引用計數(有多少進程打開該文件)
  unsigned int f_flags; 對應於open時指定的flag
  mode_t f_mode; 讀寫模式:open的mod_t mode參數
  off_t f_pos; 該文件在當前進程中的文件偏移量
  struct fown_struct f_owner; 該結構的作用是通過信號進行I/O時間通知的數據。
  unsigned int f_uid, f_gid; 文件所有者id,所有者組id
  struct file_ra_state f_ra; 在linux/include/linux/fs.h中定義,文件預讀相關
  unsigned long f_version;
  #ifdef CONFIG_SECURITY
  void *f_security;
  #endif
  
  void *private_data;
  #ifdef CONFIG_EPOLL
  
  struct list_head f_ep_links;
  spinlock_t f_ep_lock;
  #endif
  struct address_space *f_mapping;
  };


FILE結構體中的文件描述符:

文件描述符是非負整數。打開現存文件或新建文件時,內核會返回一個文件描述符。讀寫文件也需要使用文件描述符來指定待讀寫的文件。

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