Process

struct task_struct {
/* these are hardcoded - don't touch */
	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
	unsigned long flags;	/* per process flags, defined below */
	int sigpending;
	mm_segment_t addr_limit;	/* thread address space:
					 	0-0xBFFFFFFF for user-thead
						0-0xFFFFFFFF for kernel-thread
					 */
	struct exec_domain *exec_domain;
	long need_resched;

/* various fields */
	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 */
	struct linux_binfmt *binfmt;
	int exit_code, exit_signal;
	int pdeath_signal;  /*  The signal sent when the parent dies  */
	/* ??? */
	unsigned long personality;
	int dumpable:1;
	int did_exec:1;
	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. */
	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 wait4() */
	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 mm-specific or thread-specific */
	unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
	int swappable:1;
/* process credentials */
	uid_t uid,euid,suid,fsuid;
	gid_t gid,egid,sgid,fsgid;
	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[16];
/* 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;
	
/* Thread group tracking */
   	u32 parent_exec_id;
   	u32 self_exec_id;
};

A process is usually defined as an instance of a program in execution; thus, if 16 users are running vi at once, there are 16 separate processes (although theycan share the same executable code).


TASK_RUNNING

The process is either executing on the CPU or waiting to be executed.


TASK_INTERRUPTIBLE

The process is suspended (sleeping) until some conditionbecomes true. Raising a hardware interrupt, releasing a system resource theprocess is waiting for, or delivering a signal are examples of conditions that mightwake up the process, that is, put its state back toTASK_RUNNING.


TASK_UNINTERRUPTIBLE

Like the previous state, except that delivering a signalto the sleeping process leaves its state unchanged. This process state is seldom used. It is valuable, however, under certain specific conditions in which a process must waituntil a given event occurs without being interrupted. For instance, this state maybe used when a process opens a device file and the corresponding device driver startsprobing for a corresponding hardware device. The device driver must not beinterrupted until the probing is complete, or the hardware device could be left in anunpredictable state.


TASK_STOPPED

Process execution has been stopped: the process entersthis state after receiving a SIGSTOP,SIGTSTP,SIGTTIN, orSIGTTOU signal.When a process is being monitored by another (such as when a debugger executes aptrace( systemcall to monitor a test program), any signal may put the process in the TASK_STOPPED state.


TASK_ZOMBIE

Process execution is terminated, but the parent processhas not yet issued await( )-like system call (wait( ),wait3( ),wait4( ), orwaitpid()) to return information about the dead process. Before the wait( )-like call is issued, the kernel cannot discard the data contained in the dead processdescriptor because the parent could need it. 

PIDs are numbered sequentially: the PID of a newly created process is normally the PID of the previously created process incremented by one. However, for compatibility with traditional Unix systemsdeveloped for 16-bit hardware platforms, the maximum PID number allowed onLinux is 32767. When the kernel creates the 32768th process in the system, itmust start recycling the lower unused PIDs.

union task_union {
	struct task_struct task;
	unsigned long stack[2048];
};

#define for_each_task(p) \
	for (p = &init_task ; (p = p->next_task) != &init_task ; )

When looking for a new process to run on the CPU, the kernel has to consider only the runnable processes (that is, the processes in the TASK_RUNNING state). Since it would be rather inefficient to scan the whole process list, a doubly linked circular list of TASK_RUNNING processes called runqueue has been introduced.The process descriptors include the next_run and prev_run fields to implementthe runqueue list. As in the previous case, the init_taskprocessdescriptor plays the role of list header. The nr_running variable stores the total numberof runnable processes.


The wake_up_process( ) function is used tomake a process runnable. It sets the process state to TASK_RUNNING, invokes add_to_runqueue( ) to insert the process in the runqueue list, and increments nr_running. It also forces the invocation of the scheduler when theprocess is either real-time or has a dynamic priority much larger than that of the current process. Processes in a TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE state are subdivided into many classes, each of which corresponds to a specific event. In this case, the processstate does not provide enough information to retrieve the process quickly, so it is necessary to introduce additional lists of processes. These additional lists are calledwait queues.


Wait queues have several uses in the kernel, particularly for interrupt handling, process synchronization, and timing. Because these topics are discussed in later chapters, we'll just say here that a process must often wait for some event to occur, such as for a disk operation to terminate, a system resource to be released, or a fixed interval of time to elapse. Wait queues implement conditional waits on events: a process wishing to wait for a specific event places itself in the proper wait queue and relinquishes control. Therefore, a wait queue represents a set of sleeping processes, which are awakened by the kernel when some condition becomes true. A process wishing to wait for a specific condition can invoke any of the following functions: 


The sleep_on( ) function operates on the current process, which we'll call P:

void sleep_on(struct wait_queue **p)
{
struct wait_queue wait;
current->state = TASK_UNINTERRUPTIBLE;
wait.task = current;
add_wait_queue(p, &wait);
schedule( );
remove_wait_queue(p, &wait);
}
/*
 * Resource limits
 */

#define RLIMIT_CPU	0		/* CPU time in ms */
#define RLIMIT_FSIZE	1		/* Maximum filesize */
#define RLIMIT_DATA	2		/* max data size */
#define RLIMIT_STACK	3		/* max stack size */
#define RLIMIT_CORE	4		/* max core file size */
#define RLIMIT_RSS	5		/* max resident set size */
#define RLIMIT_NPROC	6		/* max number of processes */
#define RLIMIT_NOFILE	7		/* max number of open files */
#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space */
#define RLIMIT_AS	9		/* address space limit */

#define RLIM_NLIMITS	10




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值