180 likes | 361 Views
オペレーティングシステム J/K. 2004 年 10 月 25 日 酒居敬一 ( sakai.keiichi@kochi-tech.ac.jp ) http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/OS2004/. タスクとジョブ. タスクはコンピュータからみた仕事の単位 シングルタスク OS ひとつのタスクしか扱わない OS マルチタスク OS 複数のタスクを扱えるようにした OS ジョブは人間からみて目的のある一区切りの仕事 逐次的なジョブ処理 シングルタスク OS でもマルチタスク OS でも処理できる
E N D
オペレーティングシステムJ/K 2004年10月25日 酒居敬一(sakai.keiichi@kochi-tech.ac.jp) http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/OS2004/
タスクとジョブ • タスクはコンピュータからみた仕事の単位 • シングルタスクOS • ひとつのタスクしか扱わないOS • マルチタスクOS • 複数のタスクを扱えるようにしたOS • ジョブは人間からみて目的のある一区切りの仕事 • 逐次的なジョブ処理 • シングルタスクOSでもマルチタスクOSでも処理できる • 並行的なジョブ処理 • マルチタスクOSでないと処理できない
ジョブ管理とタスク管理の関係 • ジョブ実行のスケジューリング • 並行的(マルチジョブ) • 資源の量と全体の処理時間をもとに、優先度をつけて処理 • 逐次的(シングルジョブ) • ただ順番に処理する。スケジューリングの必要がない。 • タスク実行のスケジューリング • 機械的に処理される。 • タスクはOSからみた仕事の単位であるから。 • OSが資源の利用状況を見ながら、スケジューリング
タスクの存在形態 実行中タスク 実行可能タスク 実行待ちタスク 入出力 仮想記憶処理 登録済タスク 条件待ちタスク 通信 タスク 異常停止タスク 同期 未登録タスク 実行不可能タスク 生成中タスク その他条件 消滅中タスク
タスク管理 • タスクの管理表TCB(Task Control Block) • タスクの状態 • 実行可、待ち、消滅中、など • コンテキスト • レジスタ、資源管理表 • 優先順位 • タイムスライス、実行優先度、経過時間、など • TCBは線形リストを形成する(図4.12) • 線形リストによりキューを実現 • 線形リストはタスクの状態ごとに存在する
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; long interactive_credit; unsigned long long timestamp; int activated; unsigned long policy; cpumask_t cpus_allowed; unsigned int time_slice, first_time_slice; struct list_head tasks; struct list_head ptrace_children; struct list_head ptrace_list; struct mm_struct *mm, *active_mm; タスク構造体 • タスクの状態 • スケジューリングポリシー • 仮想記憶 • スレッドの情報
/* 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 did_exec:1; pid_t pid; pid_t __pgrp; /* Accessed via process_group() */ pid_t tty_old_pgrp; pid_t session; pid_t tgid; /* boolean value for session group leader */ int leader; struct task_struct *real_parent; /* real parent process (when being debugged) */ struct task_struct *parent; /* parent process */ 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_link pids[PIDTYPE_MAX]; wait_queue_head_t wait_chldexit; /* for wait4() */ 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_prof_value, it_virt_value; unsigned long it_real_incr, it_prof_incr, it_virt_incr; struct timer_list real_timer; struct list_head posix_timers; /* POSIX.1b Interval Timers */ unsigned long utime, stime, cutime, cstime; unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; /* context switch counts */ u64 start_time; unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; • タスクの詳細な状態 • インターバルタイマー • 時間 • プロセスID
/* 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; int keep_capabilities:1; struct user_struct *user; /* limits */ struct rlimit rlim[RLIM_NLIMITS]; unsigned short used_math; char comm[16]; /* file system info */ int link_count, total_link_count; struct tty_struct *tty; /* NULL if no tty */ /* 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; • タスクの制限 • ファイルシステム情報 • プロセス間通信 • シグナル
/* Thread group tracking */ u32 parent_exec_id; u32 self_exec_id; /* Protection of (de-)allocation: mm, files, fs, tty */ spinlock_t alloc_lock; /* Protection of proc_dentry*/ 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 というポインタが現在実行中のタスクを指す • タスク構造体型のデータはカーネルのメモリ空間に置かれる • タスク構造体から指される別の管理表はたくさん存在する
例: プロセスの待ち状態 入出力待ちの場合、デバイスのほうにキューを持たせる struct lp_struct { struct pardevice *dev; unsigned long flags; unsigned int chars; unsigned int time; unsigned int wait; char *lp_buffer; #ifdef LP_STATS unsigned int lastcall; unsigned int runchars; struct lp_stats stats; #endif wait_queue_head_t waitq; unsigned int last_error; struct semaphore port_mutex; wait_queue_head_t dataq; long timeout; unsigned int best_mode; unsigned int current_mode; unsigned long bits; }; struct __wait_queue { unsigned int flags; #define WQ_FLAG_EXCLUSIVE 0x01 struct task_struct * task; struct list_head task_list; #if WAITQUEUE_DEBUG long __magic; long __waker; #endif }; typedef struct __wait_queue wait_queue_t; struct __wait_queue_head { wq_lock_t lock; struct list_head task_list; #if WAITQUEUE_DEBUG long __magic; long __creator; #endif }; typedef struct __wait_queue_head wait_queue_head_t;
レジスタコンテキスト • プロセッサの持つレジスタの内容 • 汎用レジスタ • 浮動小数点数レジスタ • プログラムカウンタ、リンクレジスタ • スタックポインタ、フレームポインタ • ステータスレジスタ • マルチメディア拡張のためのレジスタ
[sakai@star linux]$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 1368 444 ? S Sep03 0:04 init [3] root 1300 0.0 0.1 1444 580 ? S Sep03 0:02 syslogd -m 0 root 1304 0.0 0.0 1364 420 ? S Sep03 0:00 klogd -x rpc 1314 0.0 0.1 1544 600 ? S Sep03 0:00 portmap root 1403 0.0 0.1 1484 536 ? S Sep03 0:00 /usr/sbin/automou named 1417 0.0 0.7 39980 3836 ? S Sep03 0:00 /usr/sbin/named - root 1456 0.0 0.1 2076 856 ? S Sep03 0:00 xinetd -stayalive ntp 1469 0.0 0.4 2392 2384 ? SL Sep03 0:08 ntpd -U ntp -g lp 1487 0.0 0.8 11800 4412 ? S Sep03 0:13 lpd Waiting root 1563 0.0 0.2 2520 1528 ? S Sep03 0:01 /usr/sbin/dhcpd e root 1630 0.0 0.1 1416 552 ? S Sep03 0:02 crond xfs 1688 0.0 0.9 9780 4944 ? S Sep03 0:21 xfs -droppriv -da root 1697 0.0 0.2 5800 1532 ? S Sep03 0:00 smbd -D root 1701 0.0 0.2 4636 1312 ? S Sep03 0:14 nmbd -D daemon 1719 0.0 0.0 1408 508 ? S Sep03 0:00 /usr/sbin/atd root 1857 0.0 0.1 2280 752 ? S Sep03 0:00 login -- sakai root 1858 0.0 0.0 1344 340 tty2 S Sep03 0:00 /sbin/mingetty tt sakai 1881 0.0 0.1 5352 980 tty1 S Sep03 0:00 -bash sakai 1910 0.0 0.0 2332 484 tty1 S Sep03 0:00 xinit root 1911 0.5 9.2 95476 47424 ? S Sep03 344:10 X -auth /home/sak sakai 1915 0.0 0.3 7076 1560 tty1 S Sep03 0:00 kterm -fn 8x16 -f sakai 1921 0.0 1.0 13416 5304 tty1 S Sep03 1:43 gkrellm -g -0+0 sakai 1931 0.0 1.6 25148 8668 tty1 S Sep03 0:14 twm sakai 1943 0.0 0.1 5348 972 pts/4 S Sep03 0:00 bash root 436 0.0 0.4 6220 2544 ? S Sep13 0:00 sendmail: accepti smmsp 444 0.0 0.4 6016 2308 ? S Sep13 0:00 sendmail: Queue r sakai 18193 0.0 0.5 8960 2628 tty1 S Oct09 0:01 aumix-X11 sakai 30076 0.1 8.8 121468 45784 tty1 R Oct19 1:54 /usr/lib/mozilla- sakai 32189 0.0 0.1 2724 776 pts/12 R 11:44 0:00 ps aux タスクの状態
プロセスとスレッド • どちらも実行のひとつの単位である • そういう意味では「タスク」とひとくくりに扱う。 • スレッドはプロセスに属する点が異なる • 同じプロセスに属す限り、資源は共有しあう • 軽量プロセス=スレッドという定義もある。 • CPUが複数個存在する場合に、同じプロセスの複数のスレッドが実行できる。 • 高速処理や効率的な処理には良いが… • 資源の競合が起きるかもしれない…
[大久保英嗣, オペレーティングシステムの基礎]
プロセスの関係 [大久保英嗣, オペレーティングシステムの基礎] 生成されたプロセスはすべて同時に動く
static int init(void * unused) { lock_kernel(); /* * Tell the world that we're going to be the grim * reaper of innocent orphaned children. * * We don't want people to have to make incorrect * assumptions about where in the task array this * can be found. */ child_reaper = current; /* Sets up cpus_possible() */ smp_prepare_cpus(max_cpus); do_pre_smp_initcalls(); smp_init(); do_basic_setup(); prepare_namespace(); /* * Ok, we have completed the initial bootup, and * we're essentially up and running. Get rid of the * initmem segments and start the user-mode stuff.. */ free_initmem(); unlock_kernel(); system_running = 1; if (open("/dev/console", O_RDWR, 0) < 0) printk("Warning: unable to open an initial console.\n"); (void) dup(0); (void) dup(0); 起動シーケンスの最終段階 /* * We try each of these until one succeeds. * * The Bourne shell can be used instead of init if we are * trying to recover a really broken machine. */ if (execute_command) run_init_process(execute_command); run_init_process("/sbin/init"); run_init_process("/etc/init"); run_init_process("/bin/init"); run_init_process("/bin/sh"); panic("No init found. Try passing init= option to kernel."); }
プロセスに対して行われる各種の基本操作 • 生成(spawn)や複製(fork) • タスク管理領域を生成するか複製するか • 消滅 • タスク管理領域を親のタスクが消す • 消えるまでの間が消滅中状態(ゾンビ) • シグナル送信 • 終了 • 停止 • 同期
プロセスに対する操作(forkによる生成) [大久保英嗣, オペレーティングシステムの基礎]