linux學習筆記之進程

1、基礎知識linux

1:進程。服務器

  1,進程ID: 非負整數,具備惟一性。網絡

    1)ID=0的進程:調度進程/交換進程。內核的一部分。不執行任何磁盤上的程序。ide

    2)ID=1的進程:init進程。函數

      1-自舉結束時,由內核調用,且不會終止。佈局

      2-用於讀取與系統有關的初始化文件。並引導系統至一個狀態。ui

      3-使用root權限運行,是全部孤兒進程的父進程。spa

    3)ID=2的進程:頁守護進程。負責支持虛擬存儲器系統的分頁操做。命令行

  2,僵死進程:已經終止,但其父進程還沒有對其進行善後處理的進程。線程

  3,進程調度。

    1)UNIX系統只提供基於調度優先級的粗粒度的控制。

    2)調度策略和調度優先級由內核肯定。

    3)進程能夠經過調整nice值來下降優先級運行。(不可提高)

    4)只有特權進程容許提升優先級。(應該指root)

  4,父進程和子進程。

    1)父進程和子進程只共享正文段。其餘僅爲副本,僅在複製的此刻保持一致。linux中,增長函數clone。能夠控制哪些部分共享,哪些部分不共享。

    2)每一個進程都有一個父進程。子進程終止時,父進程獲得通知並獲取子進程的退出狀態。

    3)一般進程的父進程是什麼?用戶進程?

    4)子進程的用途。

      1-父進程但願複製本身。例如:服務器中,等待客戶端服務請求。請求到達,複製一份子進程執行請求。父進程繼續等待請求。
      2-進程須要執行另一個程序。此狀況下,fork後將當即調用exec函數。

  5,進程組:多個進程的集合。

    1)每一個進程組由一個組長進程。組長進程的ID就是進程組ID。

    2)進程組中的最後一個進程能夠終止,也能夠轉移到另外一個進程組。

    3)進程能夠設置本身和子進程的進程組ID。但子進程調用exec後,就不能再經過父進程修改進程組ID了。

  6,會話:包含一個或多個進程組。

    1)會話ID爲會話首進程ID。會話首進程稱爲 控制進程。

    2)一個會話能夠有一個控制終端。(終端或僞終端設備)

    3)會話分爲:一個前臺進程組和多個後臺進程組。

2:進程中的用戶和用戶組。

  1,進程中分爲:實際用戶/組,有效用戶/組,設置用戶/組。

    1)實際:進程執行用戶。

    2)有效:決定進程訪問權限。一般 實際== 有效

    3)設置:設置ID由exec函數保存。當有效時,則將設置ID變爲有效ID。

    4)stat->st_mode中有兩個特殊標誌位(分別控制用戶和組)。置位做用爲:當執行此文件,進行的有效ID將便爲該文件的全部者ID。(用戶和組由不一樣位控制)

  2,設置ID能夠間接得到其餘用戶權限。須要慎重使用。(例:用戶更改本身的密碼,口令文件爲root全部。)

  3,非root權限的進程,寫文件時,設置用戶/組ID位會清除。

  4,新文件用戶ID爲:進程有效用戶ID。

  5:新文件的組ID有兩種狀況(linux 3.2.0):

    1)所在目錄的設置組ID置位時:和所在目錄的組ID同樣。

    2)所在目錄的設置組ID未置位時:進程有效組ID。

3:進程啓動和終止。

  1,啓動:

    1)內核使程序執行的惟一方法時調用一個exec函數。

  2,正常終止:

    1)從main返回。

    2)從exit, _exit, _Exit函數調用。

    3)最後一個線程: 從啓動例程返回 或 調用pthread_exit.

  3,異常終止。

    1)調用abort函數。

    2)接收到一個信號(終止相關)

    3)最後一個線程對取消請求作出響應。

3:C程序的儲存空間佈局。下列順序由高地址到低地址排序。

  1,命令行參數和環境變量。

  2,棧(stack):往低地址方向增加。保存:自動(臨時)變量 和 函數調用相關信息(形參,返回地址等)

  3,堆(head):往高地址方向增加用於動態儲存分配。(例如:new,malloc等)

  4,未初始化數據:稱之爲bss段。保存了已經未初始化的全局/靜態變量。

  5,初始化數據:保存了已經初始化的全局/靜態變量。

  6,包含常量數據:若是不細分,也能夠看成初始化數據的一部分。

  7,正文:CPU執行的機器指令保存部分。

低地址 正文(text) 常量數據(rodata) 初始化數據(data) 未初始化數據(bss) heap(堆)  -->       unused    <--  stack(棧) environment 高地址

  8,子進程建立時,擁有父進程其餘一切數據的副本,但只有exec程序執行後,才擁有棧和堆。

4:守護進程。

  1,基本概念。

    1)生存週期長的進程。

    2)一般在後臺運行。

    3)使用 ps -axj能夠顯示進程。守護進程的名字出如今方括號[ ] 中。

    4)須要在進程上下文執行工做,單不被用戶層進程上下文調用的內核組件,一般都有本身的守護進程。

    5)守護進程一般以root權限運行。

  2,產生日誌消息的方式。

    1)內核例程調用log函數。

    2)守護進程調用syslog函數產生。

    3)將日誌消息發送向UDP端口514。(網絡用戶也可使用)

  4,守護進程遵循下列通用慣例。

    1)若是守護進程使用鎖文件。通常儲存在/var/run目錄下。鎖文件名爲name.pid

    2)如支持配置選項,目錄爲 /etc 名字爲 name.conf

    3)可使用命令行啓動,一般由系統初始化腳本啓動

    4)若是守護進程由配置文件,那啓動時會讀取該文件。以後通常不會再查看。若是修改配置,須要重啓守護進程。

2、相關函數。

 

1 退出函數。
  void exit( int status )
  void _Exit( int status )
  void _eixt( int status )
  // 1 stdlib.h 包含exit _Exit.unistd.h包含_exit
  // 2 參數status 將做爲main函數的返回值返回。
  // 3 只有exit函數而沒有return返回時,部分編譯器可能會出現報錯或者警告
2 登記一個函數爲終止處理函數。
  // 1 終止處理函數將由exit函數自動調用。
  // 2 註冊順序和調用順序相反。
  // 3 能夠用sysconf函數來查詢最大終止程序數(最少支持32個)
  int atexit( void (*func)(void) );
3 內存分配函數。
  void *malloc( size_t size );  // 按大小分配內存。
  void *calloc( size_t nobj, size_t size );  // 按指定數量和指定長度的對象分配儲存空間。
  void *realloc( void *ptr, size_t newsize );  //增長/減小之前分配區的長度。
  void free( void *ptr );  //釋放內存。
  // 1 分配函數返回的指針必定要適當對齊。例:double必須在8的倍數地址單元處開始。
  // 2 由隱性的轉換規則。如無,則默認返回爲int。沒有正確的轉換類型可能致使隱性的系統錯誤。
4 環境變量函數
  int putenv( char *str );  // 參數形式:name=value。不然出錯。
  int setenv( const char *name, const char *value, int rewrite );  // 參數rewrite 非零時,會強制寫。不然,不會進行覆蓋操做。
  int unsetenv( const char *name );  // 刪除一個環境變量。
5 進程資源的設置和查詢
  int getrlimit( int resource, struct rlimit *rlptr );  // 查詢
  int setrlimit( int resource, const struct rlimit *rlptr );  // 設置(更改)
  // 1 軟限制 <= 硬限制。
  // 2 任何進程均可以下降硬限制。此過程不可逆。
  // 3 root用戶才能夠增長硬限制。
  // 4 資源限制會影響到子進程。
6 查詢 子進程終止狀態 函數。
  pid_t wait( int *statloc );
  pid_t waitpid( pid_t pid, int *statloc, int options );  
  // 1 參數pid:==-1 等待任一子進程,>0 等待與pid相同ID的子進程,==0 等待組ID等於調用進程組ID的任一子進程,<-1 等待組ID等於pid絕對值的任一子進程。
  int waitid( idtype_t idtype, id_t id, siginfo_t *infop, int options );
  pid_t wait3( int *statloc, int options, struct rusage *rusage );
  pid_t wait4( pid_t pid, int *statloc, int options, struct rusage *rusage );
  // 1 三種狀況:無終止子進程,則阻塞。有子進程終止,而且有信號發出,則返回該子進程的終止狀態。進程自己沒有任何子進程,則返回出錯。
  // 2 waitpid函數能夠選擇無終止子進程時,不阻塞
7 建立子進程
  pid_t fork(void);
  pid_t vfork(void);
  // 1 調用一次,返回兩次。父進程返回子進程ID,子進程返回0。返回順序,取決於執行順序。
  // 2 可能的失敗緣由:超過可擁有的最大ID數 或 系統中進程數量過多(系統自己已經存在問題)
  // 3 vfork函數:保證子進程先運行。且必須先exec執行子進程。如不執行,則會在父進程棧中進行運行。
  // 4 嘗試代碼後,懷疑,從fork開始,就會有2個進程同時執行 fork 以後的代碼。
8 啓動函數。
  int execl( const char * pathname, const char *arg0, ...)
  int execv( const char * pathname, char *const argv[] )
  int execle( const char * pathname, const char *arg0, ...)
  int execve( const char * pathname, char *const argv[], char *const envp[] )
  int execlp( const char * pathname, const char *arg0, ...)
  int execvp( const char * pathname, char *const argv[] )
  int fexecve( int fd, char *const argv[], char *const envp[] )
  // 1 filename包含/ 則看成路徑名。都則按照PATH環境變量,在各目錄搜索可執行文件。
  // 2 PATH變量中包含目錄表,用 :  隔開。例:PATH=/bin : /usr/bin
8 操做 進程 用戶/組 ID
  int setuid( uid_t uid );  // 設置有效用戶ID。若是有root權限,還能夠更改實際用戶。
  int setgid( gid_t gid );  // 設置有效組ID。若是有root權限,還能夠更改實際組。
  int setreuid( uid_t ruid, uid_t euid );  // 交換實際用戶和有效用戶ID。
  int setregid( gid_t rgid, gid_t egid );  // 交換實際組和有效組ID。
  int seteuid( uid_t uid );  // 僅設置有效用戶ID。
  int setegid( uid_t gid );  // 僅設置有效組ID。
  // 1 只有root用戶才能夠更改實際用戶ID。
  // 2 普通用戶不能進行權限之外的其餘操做。
9 進程調度函數(優先級)
  int nice( int incr );  // 更改優先級,只能更改進程自己的優先級(擁有root權限除外)。
  int getpriority( int which, id_t who );  // 得到nice值
  int setpriority( int which, id_t who, int value );  // 設置nice值。
  // 1 nice值輸入過大或太小,函數都會自動進行調整。
10 進程時間 結構體
  clock_t times( struct tms *buf );
  struct tms
  {
      clock_t tms_utime;   //用戶CPU時間。
      clock_t tms_stime;   //系統CPU時間。
      clock_t tms_cutime;  //用戶CPU時間,以及終止子進程時間
      clock_t tms_cstime;  //系統CPU時間,以及終止子進程時間
  }
11 進程組
  int setpgid( pid_t pid, pid_t pgid ); // 加入/建立一個進程組
  // 1 調用該函數後,進程和控制終端的聯繫會被切斷。
  pid_t tcgetpgrp( int fd);  // 獲得進程進程組ID
  int tcsetpgrp( int fd, pid_t pgrpid ); // 設置前臺進程組ID。
12 會話
  pid_t setsid( void );  // 創建一個新會話。
  pid_t tcgetsid( int fd );  // 會話首進程的進程組ID。
13 守護進程函數。
  void openlog( const char *ident, int option, int facility ); 
  void syslog( int priority, const char *format ); 
  void closelog( void );
  int setlogmask( int maskpri );

 

 

3、

相關文章
相關標籤/搜索