task_struct는 task의 한 단위로서의 역할을 하고 있다.

가끔 process와 thread와의 차이를 말끔히 정의하기 어려운 때가 있다.

하지만, Linux에서는 process와 thread의 차이를 명확히 두고 있지 않다.

즉, 다음에 나오는 task_struct가 task로서 하나의 수행 단위가 되고 있는 것이다.

process이든 thread이든 동일하게 task_struct로 생성이 되어

PCB(Process Control Block)이 된다.

하지만, 분명 thread는 자신이 포함되어 있는 process가 소멸 될 시 자신도 소멸되어야 한다.

때문에 최근에는 pid 부여를 하는 방법에서 특정 기법을 이용하여

thread가 process에 속함을 기록해 놓는다.

자세한 구조체 내용은 밑에 나열하겠다.



*** task_struct 구조체 정의 위치 ***

/usr/src/linux-2.6.12.3/include/linux/sched.h 에 존재함 (일반적으로 Kernel에 Install시에)



struct task_struct {
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
// task 의 상태를 기록하고 있다.
// -1 : Disk I/O 등으로 Blocked 되어 Blocked Queue에 있는 상태
// 0 : 현재 Runnable Queue에 존재하며 언제 실행될지 모르는 상태
// >0 : stopped 상태. Debug나 그 외의 이유로 task가 중지되어 있는 상태임

struct thread_info *thread_info;
atomic_t usage;
unsigned long flags; /* per process flags, defined below */
unsigned long ptrace;

int lock_depth; /* BKL 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;
unsigned long long sched_time; /* sched_clock time spent running */
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; // task가 종료시 부모에게 return value int pdeath_signal; /* The signal sent when the parent dies */
/* ??? */

unsigned long personality; // 현재 지원되는 Unix 버전 번호 unsigned did_exec:1; // task가 생성된 뒤에 exec()을 통해 새로운 program이 load되었는지 유무 기록 pid_t pid; // task에게 부여된 고유 번호라고 할 수 있음 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;
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;

cputime_t it_prof_expires, it_virt_expires;
unsigned long long it_sched_expires;
struct list_head cpu_timers[3];

/* 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 *thread_keyring; /* keyring private to this thread */
#endif
int oomkilladj; /* OOM kill score adjustment (bit shift). */
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
- initialized normally by flush_old_exec */
/* 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;
seccomp_t seccomp;

/* 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
#ifdef CONFIG_CPUSETS
struct cpuset *cpuset;
nodemask_t mems_allowed;
int cpuset_mems_generation;
#endif
};

+ Recent posts