1. 程式人生 > >基於Linux的源代碼

基於Linux的源代碼

角度 inf sdn acc and value 計數 notifier 設備

摘要:

本文為基於Linux 2.6.11源代碼進行的有關進程部分的簡單解析。

一、Linux下的進程

1.進程的定義

在進程模型中,計算機上所有可運行的軟件,通常也包括操作系統,被組織成若幹順序進程(sequential process),簡稱進程(process)。操作系統中最核心的概念是進程, 進程也是並發程序設計中的一個最重要、 最基本的概念。進程是一個動態的過程, 即進程有生命周期, 它擁有資源, 是程序的執行過程, 其狀態是變化的。

2.為什麽要引入進程

1.理論角度看,是對正在運行的程序過程的抽象; 2..實現角度看,是一種數據結構,目的在於清晰地刻畫動態系統的內在規律,有效管理和調度進入計算機系統主存儲器運行的程序。
3.進程的內容
一個計算機系統進程包括(或者說“擁有”)下列數據: 那個程序的可運行機器碼的一個在存儲器的映像。 分配到的存儲器(通常包括虛擬內存的一個區域)。存儲器的內容包括可運行代碼、特定於進程的數據(輸入、輸出)、調用堆棧、堆棧(用於保存運行時運數中途產生的數據)。 分配給該進程的資源的操作系統描述符,諸如文件描述符(Unix術語)或文件句柄(Windows)、數據源和數據終端。 安全特性,諸如進程擁有者和進程的權限集(可以容許的操作)。 處理器狀態(內文),諸如寄存器內容、物理存儲器尋址等。當進程正在運行時,狀態通常儲存在寄存器,其他情況在存儲器。

二、組織進程 1.
task_struct 進程屬性描述符
struct task_struct {
    volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
    struct thread_info *thread_info;
    atomic_t usage;
    unsigned long flags;    /* per process flags, defined below */
    unsigned long ptrace;

    int lock_depth;        /* Lock depth 
*/ int prio, static_prio; struct list_head run_list; prio_array_t *array; unsigned long sleep_avg; unsigned long long timestamp, last_ran; int activated; unsigned long policy; cpumask_t cpus_allowed; unsigned int time_slice, first_time_slice; #ifdef CONFIG_SCHEDSTATS struct sched_info sched_info; #endif struct list_head tasks; /* * ptrace_list/ptrace_children forms the list of my children * that were stolen by a ptracer. */ struct list_head ptrace_children; struct list_head ptrace_list; struct mm_struct *mm, *active_mm; /* task state */ struct linux_binfmt *binfmt; long exit_state; int exit_code, exit_signal; int pdeath_signal; /* The signal sent when the parent dies */ /* ??? */ unsigned long personality; unsigned did_exec:1; pid_t pid; pid_t tgid; /* * pointers to (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with * p->parent->pid) */ struct task_struct *real_parent; /* real parent process (when being debugged) */ struct task_struct *parent; /* parent process */ /* * children/sibling forms the list of my children plus the * tasks I‘m ptracing. */ struct list_head children; /* list of my children */ struct list_head sibling; /* linkage in my parent‘s children list */ struct task_struct *group_leader; /* threadgroup leader */ /* PID/PID hash table linkage. */ struct pid pids[PIDTYPE_MAX]; struct completion *vfork_done; /* for vfork() */ int __user *set_child_tid; /* CLONE_CHILD_SETTID */ int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ unsigned long rt_priority; unsigned long it_real_value, it_real_incr; cputime_t it_virt_value, it_virt_incr; cputime_t it_prof_value, it_prof_incr; struct timer_list real_timer; cputime_t utime, stime; unsigned long nvcsw, nivcsw; /* context switch counts */ struct timespec start_time; /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ unsigned long min_flt, maj_flt; /* process credentials */ uid_t uid,euid,suid,fsuid; gid_t gid,egid,sgid,fsgid; struct group_info *group_info; kernel_cap_t cap_effective, cap_inheritable, cap_permitted; unsigned keep_capabilities:1; struct user_struct *user; #ifdef CONFIG_KEYS struct key *session_keyring; /* keyring inherited over fork */ struct key *process_keyring; /* keyring private to this process (CLONE_THREAD) */ struct key *thread_keyring; /* keyring private to this thread */ #endif int oomkilladj; /* OOM kill score adjustment (bit shift). */ char comm[TASK_COMM_LEN]; /* file system info */ int link_count, total_link_count; /* ipc stuff */ struct sysv_sem sysvsem; /* CPU-specific state of this task */ struct thread_struct thread; /* filesystem information */ struct fs_struct *fs; /* open file information */ struct files_struct *files; /* namespace */ struct namespace *namespace; /* signal handlers */ struct signal_struct *signal; struct sighand_struct *sighand; sigset_t blocked, real_blocked; struct sigpending pending; unsigned long sas_ss_sp; size_t sas_ss_size; int (*notifier)(void *priv); void *notifier_data; sigset_t *notifier_mask; void *security; struct audit_context *audit_context; /* Thread group tracking */ u32 parent_exec_id; u32 self_exec_id; /* Protection of (de-)allocation: mm, files, fs, tty, keyrings */ spinlock_t alloc_lock; /* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */ spinlock_t proc_lock; /* context-switch lock */ spinlock_t switch_lock; /* journalling filesystem info */ void *journal_info; /* VM state */ struct reclaim_state *reclaim_state; struct dentry *proc_dentry; struct backing_dev_info *backing_dev_info; struct io_context *io_context; unsigned long ptrace_message; siginfo_t *last_siginfo; /* For ptrace use. */ /* * current io wait handle: wait queue entry to use for io waits * If this thread is processing aio, this points at the waitqueue * inside the currently handled kiocb. It may be NULL (i.e. default * to a stack based synchronous wait) if its doing sync IO. */ wait_queue_t *io_wait; /* i/o counters(bytes read/written, #syscalls */ u64 rchar, wchar, syscr, syscw; #if defined(CONFIG_BSD_PROCESS_ACCT) u64 acct_rss_mem1; /* accumulated rss usage */ u64 acct_vm_mem1; /* accumulated virtual memory usage */ clock_t acct_stimexpd; /* clock_t-converted stime since last update */ #endif #ifdef CONFIG_NUMA struct mempolicy *mempolicy; short il_next; #endif };

其中

    1. 1)unsigned short pid 為用戶標識
      (2)int pid 為進程標識
      (3)int processor標識用戶正在使用的CPU,以支持對稱多處理機方式;
      (4)volatile long state 標識進程的狀態,可為下列六種狀態之一:
        可運行狀態(TASK-RUNING);
        可中斷阻塞狀態(TASK-UBERRUPTIBLE)
        不可中斷阻塞狀態(TASK-UNINTERRUPTIBLE)
        僵死狀態(TASK-ZOMBLE)
        暫停態(TASK_STOPPED)
        交換態(TASK_SWAPPING)
      (5)long prority表示進程的優先級
      (6)unsigned long rt_prority 表示實時進程的優先級,對於普通進程無效
      (7)long counter 為進程動態優先級計數器,用於進程輪轉調度算法
      (8)unsigned long policy 表示進程調度策略,其值為下列三種情況之一:
        SCHED_OTHER(值為0)對應普通進程優先級輪轉法(round robin)
        SCHED_FIFO(值為1)對應實時進程先來先服務算法;
        SCHED_RR(值為2)對應實時進程優先級輪轉法
      (9)struct task_struct *next_task,*prev_task為進程PCB雙向鏈表的前後項指針
      (10)struct task_struct *next_run,*prev_run為就緒隊列雙向鏈表的前後項指針(11)struct task_struct *p_opptr,*p_pptr,*p_cptr,*p_ysptr,*p_ptr指明進程家族間的關系,分別為指向祖父進程、父進程、子進程以及新老進程的指針。

2.進程的狀態轉換(網圖侵刪)

技術分享圖片

3.進程調度

 __wait_event_interruptible_timeout(wq, condition, ret)        do {                                        DEFINE_WAIT(__wait);                                                                for (;;) {                                    prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE);            if (condition)                                    break;                                if (!signal_pending(current)) {                            ret = schedule_timeout(ret);                        if (!ret)                                    break;                                continue;                            }                                    ret = -ERESTARTSYS;                            break;                                }                                    finish_wait(&wq, &__wait);                    } while (0)

1、進程調度的時機
  進程狀態轉換:
  當前進程時間片用完
  設備驅動程序運行時
  從內核態返回到用戶態
  從中斷或系統調用中返回;
  進程重新允許搶占;

  調用該函數為主動進入休眠。

   調度程序運行時,要在所有處於可運行狀態的進程中選擇最值得運行的進程投入運行。

1.進程的調度策略(policy)
  SCHED_NORMAL(SCHED_OTHER):普通的分時進程
  SCHED_FIFO :先入先進的實時進程
  SCHED_RR: 時間片輪轉的實時進程
  SCHED_BATCH:批處理進程,與普通進程不被搶占的情況類似
  SCHED_IDLE:CPU空閑時,即SCHED_IDLE等級以外處於可執行狀態的進程消失時,將被賦予執行權。也就是它將成為優先級最低的進程。
  linux對調度策略定義如下:
 

  #define SCHED_NORMAL            0
  #define SCHED_FIFO              1
#define SCHED_RR 2
#define SCHED_BATCH 3  #define SCHED_IDLE 5

進程的調度算法:

  1.先來先服務FCFS:該算法即可用於作業調度,也可用於進程調度

  2.短作業優先/短進程優先 :SJF/ SPF :選擇剩余時間最短的

  3.優先權優先 FPF

  4.時間片輪詢法

4.對Linux進程模型的看法

一個優秀的系統無法脫離優秀的結構而存。作為一個開源的操作系統,Linux建立在許許多多誌同道合的開發者的緊密合作之上。通過閱讀代碼,我們可以發現其書寫的規範性和命名極強的可讀性。也許這提醒了我們,在當前的環境下,多人協作並構築出一個可行的標準是極其重要的。

參考材料:

https://elixir.bootlin.com/linux/v2.6.11/ident/sched_class

https://www.ibm.com/developerworks/cn/linux/l-task-killable/

https://www.cnblogs.com/ck1020/p/6089970.html

https://blog.csdn.net/shuizhilan/article/details/6642040

https://blog.csdn.net/kevin_hcy/article/details/6064518

基於Linux的源代碼