熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

讀核日記(三)

2022-06-13   來源: Oracle 

  作者: sunmoon
  
  在linux 中每一個進程都由task_struct 數據結構來定義 task_struct就是我們通常所說的PCB
  
  她是對進程控制的唯一手段也是最有效的手段
  
  當我們調用fork() 時 系統會為我們產生一個task_struct結構然後從父進程那裡繼承一些數據
  
  並把新的進程插入到進程樹中 以待進行進程管理因此了解task_struct的結構對於我們理解任務
  
  調度(在linux 中任務和進程是同一概念)的關鍵在進行剖析task_struct的定義之前 我們先按照
  
  我們的理論推一下它的結構
  
   進程狀態 將紀錄進程在等待運行或死鎖
  
   調度信息 由哪個調度函數調度怎樣調度等
  
   進程的通訊狀況
  
  因為要插入進程樹必須有聯系父子兄弟的指針 當然是task_struct型
  
  時間信息 比如計算好執行的時間 以便cpu 分配
  
  標號 決定改進程歸屬
  
  可以讀寫打開的一些文件信息
  
   進程上下文和內核上下文
  
  處理器上下文
  
  內存信息
  
  因為每一個PCB都是這樣的 只有這些結構 才能滿足一個進程的所有要求
  
  打開/include/linux/schedh 找到task_struct 的定義
  
  struct task_struct {
  
  /* these are hardcoded dont touch */
  
  這裡是一些硬件設置對程序原來說是透明的 其中state 說明了該進程是否可以執行
  
  還是可中斷等信息 Flage 是進程號 在調用 fork() 時給出addr_limit 是區分內核進程
  
  與普通進程在內存存放的位置不同
  
  volatile long state; /* unrunnable runnable > stopped */
  
  unsigned long flags; /* per process flags defined below */
  
  int sigpending;
  
  mm_segment_t addr_limit; /* thread address space:
  
  xBFFFFFFF for userthead
  
  xFFFFFFFF for kernelthread
  
  */
  
  struct exec_domain *exec_domain;
  
  long need_resched;
  
   
  
  /* various fields */
  
  count 是 計數器 priorrity 是優先級
  
  long counter;
  
  long priority;
  
  cycles_t avg_slice;
  
  /* SMP and runqueue state */
  
  為多處理機定義的變量
  
  int has_cpu;
  
  int processor;
  
  int last_processor;
  
  int lock_depth;
  
  /* Lock depth We can context switch in and out of holding a syscall kernel lock */
  
  為了在進程樹中排序 定義的父子兄弟指針
  
  struct task_struct *next_task *prev_task;
  
  struct task_struct *next_run *prev_run;
  
   
  
  /* task state */
  
  定義可 task 運行的狀態 以及信號
  
  struct linux_binfmt *binfmt;
  
  int exit_code exit_signal;
  
  int pdeath_signal; /* The signal sent when the parent dies */
  
  /* 定義可進程的用戶號用戶組以及進程組*/
  
  unsigned long personality;
  
  int dumpable:;
  
  int did_exec:;
  
  pid_t pid;
  
  pid_t pgrp;
  
  pid_t tty_old_pgrp;
  
  pid_t session;
  
  /* boolean value for session group leader */
  
  是不是進程組的頭文件
  
  int leader;
  
  /*
  
  * pointers to (original) parent process youngest child younger sibling
  
  * older sibling respectively (p>father can be replaced with
  
  * p>p_pptr>pid)
  
  */
  
  父子進程的一些指針
  
  struct task_struct *p_opptr *p_pptr *p_cptr *p_ysptr *p_osptr;
  
   
  
  /* PID hash table linkage */
  
  在調度中用的一些hash 表
  
  struct task_struct *pidhash_next;
  
  struct task_struct **pidhash_pprev;
  
   
  
  /* Pointer to task[] array linkage */
  
  struct task_struct **tarray_ptr;
  
   
  
  struct wait_queue *wait_chldexit; /* for wait() 等待隊列 */
  
  struct semaphore *vfork_sem; /* for vfork() */
  
  unsigned long policy rt_priority;
  
  unsigned long it_real_value it_prof_value it_virt_value;
  
  進程的性質因為實時進程與普通進程的調度算法不一樣所以應有變量區分
  
  下面是進程的一些時間信息
  
  unsigned long it_real_incr it_prof_incr it_virt_incr;
  
  struct timer_list real_timer;
  
  struct tms times;
  
  unsigned long start_time;
  
  long per_cpu_utime[NR_CPUS] per_cpu_stime[NR_CPUS];定義了時間片的大小
  
  /* mm fault and swap info: this can arguably be seen as either mmspecific or
  threadspecific */
  
  內存信息
  
  unsigned long min_flt maj_flt nswap cmin_flt cmaj_flt cnswap;
  
  int swappable:;
  
  /* process credentials */
  
  uid_t uideuidsuidfsuid;
  
  gid_t gidegidsgidfsgid;
  
  int ngroups;
  
  gid_t groups[NGROUPS];
  
  kernel_cap_t cap_effective cap_inheritable cap_permitted;
  
  struct user_struct *user;
  
  以下英文注釋很清楚
  
  /* limits */
  
  struct rlimit rlim[RLIM_NLIMITS];
  
  unsigned short used_math;
  
  char comm[];
  
  /* file system info */
  
  int link_count;
  
  struct tty_struct *tty; /* NULL if no tty */
  
  /* ipc stuff */
  
   
  
  struct sem_undo *semundo;
  
  struct sem_queue *semsleeping;
  
  /* tss for this task */
  
  struct thread_struct tss;
  
  /* filesystem information */
  
  struct fs_struct *fs;
  
  /* open file information */
  
  struct files_struct *files;
  
  /* memory management info */
  
  struct mm_struct *mm;
  
   
  
  /* signal handlers */
  
  spinlock_t sigmask_lock; /* Protects signal and blocked */
  
  struct signal_struct *sig;
  
  sigset_t signal blocked;
  
  struct signal_queue *sigqueue **sigqueue_tail;
  
  unsigned long sas_ss_sp;
  
  size_t sas_ss_size;
  
  };
  
  在分析完 這個結構之後 還有很多問題要想 也許不能讀 但框架要搞好需要向的問題有以下幾個
  
  在task_struct 中用的常量在那裡定義呢 如最大進程個數 最多支持的cpu 個數等等
  
  在調用fork() 時 系統是分配一塊內存 會是這樣麼
  
  malloc(sizeof(struct task_struck))
  
  拷貝一些變量還是和服進程公用一部分內存malloc 函數怎麼實現(在內存管理那一部分但此處
  我認為不能不想)
  
  對於線程來說 又如何實現呢?
  
   調度策略函數 schedul()
  
  有幾種形勢 時間片輪轉 搶占式優先級搶占式 多級反饋制除了時間片輪轉外都要對進程樹
  進行遍歷(對於實時進程
  
  的fifo機制不用)linux 是怎樣保證了高效呢?如果把最大線成數修改 效率會不會降低
  
   進程通訊用到的管道信號結構如何
  
  待續

From:http://tw.wingwit.com/Article/program/Oracle/201311/18993.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.