简介
计算机体系中控制进程的模块我们把它叫做进程控制模块,即PCB。它是对进程控制的唯一手段也是最有效的手段。 在Linux 中PCB是由task_struct 数据结构来定义的,当我们调用fork() 时, 系统会为我们产生一个task_struct结构。然后从父进程,那里继承一些数据, 并把新的进程插入到进程树中, 以待进行进程管理。因此了解task_struct的结构对于我们理解进程调度的关键。
得益于Linux的开源性,我们可以在Linux源码中找到task_struct的定义,它存在于根目录下usr/include/linux/sched.h的文件中。也可以在github中查看。 https://github.com/torvalds/linux/blob/master/include/linux/sched.h 这是linux之父linus在github中给出的sched.h的完整头文件,有兴趣的可以详读。
下面我们就sched.h中的一些重要成员做出介绍
#ifndef _SCHED_H
#define _SCHED_H
#define NR_TASKS 64 // 系统中同时最多任务(进程)数。
#define HZ 100 // 定义系统时钟滴答频率(1 百赫兹,每个滴答10ms)
#define FIRST_TASK task[0] // 任务0 比较特殊,所以特意给它单独定义一个符号。
#define LAST_TASK task[NR_TASKS-1] // 任务数组中的最后一项任务。
#include <linux/head.h> // head 头文件,定义了段描述符的简单结构,和几个选择符常量。
#include <linux/fs.h> // 文件系统头文件。定义文件表结构(file,buffer_head,m_inode 等)。
#include <linux/mm.h> // 内存管理头文件。含有页面大小定义和一些页面释放函数原型。
#include <signal.h> // 信号头文件。定义信号符号常量,信号结构以及信号操作函数原型。
#if (NR_OPEN > 32)
#error "Currently the close-on-exec-flags are in one word, max 32 files/proc"
#endif
#define TASK_RUNNING 0 // 进程正在运行或已准备就绪。
#define TASK_INTERRUPTIBLE 1 // 进程处于可中断等待状态。
#define TASK_UNINTERRUPTIBLE 2 // 进程处于不可中断等待状态,主要用于I/O 操作等待。
#define TASK_ZOMBIE 3 // 进程处于僵死状态,已经停止运行,但父进程还没发信号。
#define TASK_STOPPED 4 // 进程已停止。
#ifndef NULL
#define NULL ((void *) 0) // 定义NULL 为空指针。
#endif
extern int copy_page_tables (unsigned
long from, unsigned
long to,
long size);
extern int free_page_tables (unsigned
long from, unsigned
long size);
extern void sched_init (
void);
extern void schedule (
void);
extern void trap_init (
void);
extern void panic (
const char *str);
extern int tty_write (unsigned minor,
char *buf,
int count);
typedef
int (*fn_ptr) ();
struct i387_struct
{
long cwd;
long swd;
long twd;
long fip;
long fcs;
long foo;
long fos;
long st_space[
20];
};
struct tss_struct
{
long back_link;
long esp0;
long ss0;
long esp1;
long ss1;
long esp2;
long ss2;
long cr3;
long eip;
long eflags;
long eax, ecx, edx, ebx;
long esp;
long ebp;
long esi;
long edi;
long es;
long cs;
long ss;
long ds;
long fs;
long gs;
long ldt;
long trace_bitmap;
struct i387_struct i387;
};
struct task_struct
{
long state;
long counter;
long priority;
long signal;
struct sigaction sigaction[
32];
long blocked;
int exit_code;
unsigned
long start_code, end_code, end_data, brk, start_stack;
long pid, father, pgrp, session, leader;
unsigned
short uid, euid, suid;
unsigned
short gid, egid, sgid;
long alarm;
long utime, stime, cutime, cstime, start_time;
unsigned
short used_math;
int tty;
unsigned
short umask;
struct m_inode *pwd;
struct m_inode *root;
struct m_inode *executable;
unsigned
long close_on_exec;
struct file *filp[NR_OPEN];
struct desc_struct ldt[
3];
struct tss_struct tss;
};
#define INIT_TASK \
{
0,
15,
15, \
0,
{
{
}
,}
,
0, \
0,
0,
0,
0,
0,
0, \
0, -
1,
0,
0,
0, \
0,
0,
0,
0,
0,
0, \
0,
0,
0,
0,
0,
0, \
0, \
-
1,
0022, NULL, NULL, NULL,
0, \
{
NULL,}
, \
{
\
{
0,
0}
,
{
0x9f,
0xc0fa00}
, \
{
0x9f,
0xc0f200}
, \
}
,
{
0, PAGE_SIZE + (
long) &init_task,
0x10,
0,
0,
0,
0, (
long) &pg_dir, \
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0x17,
0x17,
0x17,
0x17,
0x17,
0x17, _LDT (
0),
0x80000000,
{
}
}
,}
extern struct task_struct *task[NR_TASKS];
extern struct task_struct *last_task_used_math;
extern struct task_struct *current;
extern long volatile jiffies;
extern long startup_time;
#define CURRENT_TIME (startup_time+jiffies/HZ) // 当前时间(秒数)。
extern void add_timer (
long jiffies,
void (*fn) (
void));
extern void sleep_on (
struct task_struct **p);
extern void interruptible_sleep_on (
struct task_struct **p);
extern void wake_up (
struct task_struct **p);
#define FIRST_TSS_ENTRY 4
#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
#define ltr(n) __asm__( "ltr %%ax":: "a" (_TSS(n)))
#define lldt(n) __asm__( "lldt %%ax":: "a" (_LDT(n)))
#define str(n) \
__asm__(
"str %%ax\n\t" \
"subl %2,%
转载请注明原文地址: https://ju.6miu.com/read-673375.html