⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000045.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<HTML><HEAD>  <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人:&nbsp;clamor&nbsp;(clamor),&nbsp;信区:&nbsp;Linux&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>标&nbsp;&nbsp;题:&nbsp;Linux&nbsp;Kernel&nbsp;Internals-2(Process&nbsp;and&nbsp;IM)&nbsp;<BR>发信站:&nbsp;BBS&nbsp;水木清华站&nbsp;(Tue&nbsp;Dec&nbsp;19&nbsp;21:28:56&nbsp;2000)&nbsp;<BR>&nbsp;<BR>2.&nbsp;Process&nbsp;and&nbsp;Interrupt&nbsp;Management&nbsp;<BR>2.1&nbsp;Task&nbsp;Structure&nbsp;and&nbsp;Process&nbsp;Table&nbsp;<BR>Every&nbsp;process&nbsp;under&nbsp;Linux&nbsp;is&nbsp;dynamically&nbsp;allocated&nbsp;a&nbsp;'struct&nbsp;task_struct'&nbsp;st&nbsp;<BR>ructure.&nbsp;The&nbsp;maximum&nbsp;number&nbsp;of&nbsp;processes&nbsp;that&nbsp;can&nbsp;be&nbsp;created&nbsp;on&nbsp;the&nbsp;Linux&nbsp;sy&nbsp;<BR>stem&nbsp;is&nbsp;limited&nbsp;only&nbsp;by&nbsp;the&nbsp;amount&nbsp;of&nbsp;physical&nbsp;memory&nbsp;present,&nbsp;and&nbsp;is&nbsp;equal&nbsp;&nbsp;<BR>to&nbsp;(see&nbsp;kernel/fork.c:fork_init()):&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;The&nbsp;default&nbsp;maximum&nbsp;number&nbsp;of&nbsp;threads&nbsp;is&nbsp;set&nbsp;to&nbsp;a&nbsp;safe&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;value:&nbsp;the&nbsp;thread&nbsp;structures&nbsp;can&nbsp;take&nbsp;up&nbsp;at&nbsp;most&nbsp;half&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;of&nbsp;memory.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_threads&nbsp;=&nbsp;mempages&nbsp;/&nbsp;(THREAD_SIZE/PAGE_SIZE)&nbsp;/&nbsp;2;&nbsp;<BR>which&nbsp;on&nbsp;IA32&nbsp;architecture&nbsp;basically&nbsp;means&nbsp;'num_physpages/4'&nbsp;so,&nbsp;for&nbsp;example&nbsp;<BR>&nbsp;on&nbsp;512M&nbsp;machine&nbsp;you&nbsp;can&nbsp;create&nbsp;32k&nbsp;threads&nbsp;which&nbsp;is&nbsp;a&nbsp;considerable&nbsp;improvem&nbsp;<BR>ent&nbsp;over&nbsp;the&nbsp;4k-epsilon&nbsp;limit&nbsp;for&nbsp;older&nbsp;(2.2&nbsp;and&nbsp;earlier)&nbsp;kernels.&nbsp;Moreover,&nbsp;<BR>&nbsp;this&nbsp;can&nbsp;be&nbsp;changed&nbsp;at&nbsp;runtime&nbsp;using&nbsp;KERN_MAX_THREADS&nbsp;sysctl(2)&nbsp;or&nbsp;simply&nbsp;u&nbsp;<BR>sing&nbsp;procfs&nbsp;interface&nbsp;to&nbsp;kernel&nbsp;tunables:&nbsp;<BR>#&nbsp;cat&nbsp;/proc/sys/kernel/threads-max&nbsp;<BR>32764&nbsp;<BR>#&nbsp;echo&nbsp;100000&nbsp;&nbsp;/proc/sys/kernel/threads-max&nbsp;<BR>#&nbsp;cat&nbsp;/proc/sys/kernel/threads-max&nbsp;<BR>100000&nbsp;<BR>#&nbsp;gdb&nbsp;-q&nbsp;vmlinux&nbsp;/proc/kcore&nbsp;<BR>Core&nbsp;was&nbsp;generated&nbsp;by&nbsp;`BOOT_IMAGE=240ac18&nbsp;ro&nbsp;root=306&nbsp;video=matrox:vesa:0x11&nbsp;<BR>8'.&nbsp;<BR>#0&nbsp;&nbsp;0x0&nbsp;in&nbsp;??&nbsp;()&nbsp;<BR>(gdb)&nbsp;p&nbsp;max_threads&nbsp;<BR>$1&nbsp;=&nbsp;100000&nbsp;<BR>The&nbsp;set&nbsp;of&nbsp;processes&nbsp;on&nbsp;the&nbsp;Linux&nbsp;system&nbsp;is&nbsp;represented&nbsp;as&nbsp;a&nbsp;collection&nbsp;of&nbsp;'&nbsp;<BR>struct&nbsp;task_struct'&nbsp;structures&nbsp;which&nbsp;are&nbsp;linked&nbsp;in&nbsp;two&nbsp;ways:&nbsp;<BR>1.&nbsp;as&nbsp;a&nbsp;hashtable,&nbsp;hashed&nbsp;by&nbsp;pid&nbsp;<BR>2.&nbsp;as&nbsp;a&nbsp;circular,&nbsp;doubly-linked&nbsp;list&nbsp;using&nbsp;p-next_task&nbsp;and&nbsp;p-prev_task&nbsp;point&nbsp;<BR>ers&nbsp;<BR>The&nbsp;hashtable&nbsp;is&nbsp;called&nbsp;pidhash[]&nbsp;and&nbsp;is&nbsp;defined&nbsp;in&nbsp;include/linux/sched.h:&nbsp;<BR>/*&nbsp;PID&nbsp;hashing.&nbsp;(shouldnt&nbsp;this&nbsp;be&nbsp;dynamic?)&nbsp;*/&nbsp;<BR>#define&nbsp;PIDHASH_SZ&nbsp;(4096&nbsp;&nbsp;2)&nbsp;<BR>extern&nbsp;struct&nbsp;task_struct&nbsp;*pidhash[PIDHASH_SZ];&nbsp;<BR>#define&nbsp;pid_hashfn(x)&nbsp;&nbsp;&nbsp;((((x)&nbsp;&nbsp;8)&nbsp;^&nbsp;(x))&nbsp;&amp;&nbsp;(PIDHASH_SZ&nbsp;-&nbsp;1))&nbsp;<BR>The&nbsp;tasks&nbsp;are&nbsp;hashed&nbsp;by&nbsp;their&nbsp;pid&nbsp;value&nbsp;and&nbsp;the&nbsp;above&nbsp;hashing&nbsp;function&nbsp;is&nbsp;su&nbsp;<BR>pposed&nbsp;to&nbsp;distribute&nbsp;the&nbsp;elements&nbsp;uniformly&nbsp;in&nbsp;their&nbsp;domain&nbsp;(0&nbsp;to&nbsp;PID_MAX-1)&nbsp;<BR>.&nbsp;The&nbsp;hashtable&nbsp;is&nbsp;used&nbsp;to&nbsp;quickly&nbsp;find&nbsp;a&nbsp;task&nbsp;by&nbsp;given&nbsp;pid,&nbsp;using&nbsp;find_task&nbsp;<BR>_pid()&nbsp;inline&nbsp;from&nbsp;include/linux/sched.h:&nbsp;<BR>static&nbsp;inline&nbsp;struct&nbsp;task_struct&nbsp;*find_task_by_pid(int&nbsp;pid)&nbsp;<BR>{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;task_struct&nbsp;*p,&nbsp;**htable&nbsp;=&nbsp;&amp;pidhash[pid_hashfn(pid)];&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(p&nbsp;=&nbsp;*htable;&nbsp;p&nbsp;&amp;&amp;&nbsp;p-pid&nbsp;!=&nbsp;pid;&nbsp;p&nbsp;=&nbsp;p-pidhash_next)&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;p;&nbsp;<BR>}&nbsp;<BR>The&nbsp;tasks&nbsp;on&nbsp;each&nbsp;hashlist&nbsp;(i.e.&nbsp;hashed&nbsp;to&nbsp;the&nbsp;same&nbsp;value)&nbsp;are&nbsp;linked&nbsp;by&nbsp;p-p&nbsp;<BR>idhash_next/pidhash_pprev&nbsp;which&nbsp;are&nbsp;used&nbsp;by&nbsp;hash_pid()&nbsp;and&nbsp;unhash_pid()&nbsp;to&nbsp;i&nbsp;<BR>nsert&nbsp;and&nbsp;remove&nbsp;a&nbsp;given&nbsp;process&nbsp;into&nbsp;the&nbsp;hashtable.&nbsp;These&nbsp;are&nbsp;done&nbsp;under&nbsp;pr&nbsp;<BR>otection&nbsp;of&nbsp;the&nbsp;rw&nbsp;spinlock&nbsp;called&nbsp;'tasklist_lock'&nbsp;taken&nbsp;for&nbsp;WRITE.&nbsp;<BR>The&nbsp;circular&nbsp;doubly-linked&nbsp;list&nbsp;that&nbsp;uses&nbsp;p-next_task/prev_task&nbsp;is&nbsp;maintaine&nbsp;<BR>d&nbsp;so&nbsp;that&nbsp;one&nbsp;could&nbsp;go&nbsp;through&nbsp;all&nbsp;tasks&nbsp;on&nbsp;the&nbsp;system&nbsp;easily.&nbsp;This&nbsp;is&nbsp;achie&nbsp;<BR>ved&nbsp;by&nbsp;for_each_task()&nbsp;macro&nbsp;from&nbsp;include/linux/sched.h:&nbsp;<BR>#define&nbsp;for_each_task(p)&nbsp;\&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(p&nbsp;=&nbsp;&amp;init_task&nbsp;;&nbsp;(p&nbsp;=&nbsp;p-next_task)&nbsp;!=&nbsp;&amp;init_task&nbsp;;&nbsp;)&nbsp;<BR>The&nbsp;users&nbsp;of&nbsp;for_each_task()&nbsp;should&nbsp;take&nbsp;tasklist_lock&nbsp;for&nbsp;READ.&nbsp;Note&nbsp;that&nbsp;f&nbsp;<BR>or_each_task()&nbsp;is&nbsp;using&nbsp;init_task&nbsp;to&nbsp;mark&nbsp;the&nbsp;beginning&nbsp;(and&nbsp;end)&nbsp;of&nbsp;the&nbsp;lis&nbsp;<BR>t&nbsp;-&nbsp;this&nbsp;is&nbsp;safe&nbsp;because&nbsp;the&nbsp;idle&nbsp;task&nbsp;(pid&nbsp;0)&nbsp;never&nbsp;exits.&nbsp;<BR>The&nbsp;modifiers&nbsp;of&nbsp;the&nbsp;process&nbsp;hashtable&nbsp;or/and&nbsp;the&nbsp;process&nbsp;table&nbsp;links,&nbsp;notab&nbsp;<BR>ly&nbsp;fork,&nbsp;exit&nbsp;and&nbsp;ptrace&nbsp;must&nbsp;take&nbsp;the&nbsp;tasklist_lock&nbsp;for&nbsp;WRITE.&nbsp;What&nbsp;is&nbsp;more&nbsp;<BR>&nbsp;interesting&nbsp;is&nbsp;that&nbsp;the&nbsp;writers&nbsp;must&nbsp;also&nbsp;disable&nbsp;interrupts&nbsp;on&nbsp;the&nbsp;local&nbsp;c&nbsp;<BR>pu.&nbsp;The&nbsp;reason&nbsp;for&nbsp;this&nbsp;is&nbsp;not&nbsp;trivial.&nbsp;The&nbsp;send_sigio()&nbsp;walks&nbsp;the&nbsp;task&nbsp;list&nbsp;<BR>&nbsp;and&nbsp;thus&nbsp;takes&nbsp;tasklist_lock&nbsp;for&nbsp;READ&nbsp;and&nbsp;it&nbsp;is&nbsp;called&nbsp;from&nbsp;kill_fasync()&nbsp;i&nbsp;<BR>n&nbsp;the&nbsp;interrupt&nbsp;context.&nbsp;This&nbsp;is&nbsp;why&nbsp;writers&nbsp;must&nbsp;disable&nbsp;the&nbsp;interrupts&nbsp;whi&nbsp;<BR>le&nbsp;the&nbsp;readers&nbsp;don't&nbsp;need&nbsp;to.&nbsp;<BR>Now&nbsp;that&nbsp;we&nbsp;understand&nbsp;how&nbsp;the&nbsp;task_struct&nbsp;structures&nbsp;are&nbsp;linked&nbsp;together,&nbsp;l&nbsp;<BR>et&nbsp;us&nbsp;examine&nbsp;the&nbsp;members&nbsp;of&nbsp;task_struct.&nbsp;They&nbsp;loosely&nbsp;corresponds&nbsp;to&nbsp;the&nbsp;me&nbsp;<BR>mbers&nbsp;of&nbsp;UNIX&nbsp;'struct&nbsp;proc'&nbsp;and&nbsp;'struct&nbsp;user'&nbsp;combined&nbsp;together.&nbsp;<BR>The&nbsp;other&nbsp;versions&nbsp;of&nbsp;UNIX&nbsp;separated&nbsp;the&nbsp;task&nbsp;state&nbsp;information&nbsp;into&nbsp;part&nbsp;wh&nbsp;<BR>ich&nbsp;should&nbsp;be&nbsp;kept&nbsp;memory-resident&nbsp;at&nbsp;all&nbsp;times&nbsp;(called&nbsp;'proc&nbsp;structure'&nbsp;whi&nbsp;<BR>ch&nbsp;includes&nbsp;process&nbsp;state,&nbsp;scheduling&nbsp;information&nbsp;etc.)&nbsp;and&nbsp;part&nbsp;which&nbsp;is&nbsp;on&nbsp;<BR>ly&nbsp;needed&nbsp;when&nbsp;the&nbsp;process&nbsp;is&nbsp;running&nbsp;(called&nbsp;'u&nbsp;area'&nbsp;which&nbsp;includes&nbsp;file&nbsp;d&nbsp;<BR>escriptor&nbsp;table,&nbsp;disk&nbsp;quota&nbsp;information&nbsp;etc.).&nbsp;The&nbsp;only&nbsp;reason&nbsp;for&nbsp;such&nbsp;ugly&nbsp;<BR>&nbsp;design&nbsp;was&nbsp;that&nbsp;memory&nbsp;was&nbsp;a&nbsp;very&nbsp;scarce&nbsp;resource.&nbsp;Modern&nbsp;operating&nbsp;systems&nbsp;<BR>&nbsp;(well,&nbsp;only&nbsp;Linux&nbsp;at&nbsp;the&nbsp;moment&nbsp;but&nbsp;others,&nbsp;e.g.&nbsp;FreeBSD&nbsp;seem&nbsp;to&nbsp;improve&nbsp;in&nbsp;<BR>&nbsp;this&nbsp;direction&nbsp;towards&nbsp;Linux)&nbsp;do&nbsp;not&nbsp;need&nbsp;such&nbsp;separation&nbsp;and&nbsp;therefore&nbsp;mai&nbsp;<BR>ntain&nbsp;process&nbsp;state&nbsp;in&nbsp;a&nbsp;kernel&nbsp;memory-resident&nbsp;data&nbsp;structure&nbsp;at&nbsp;all&nbsp;times.&nbsp;<BR>&nbsp;<BR>The&nbsp;task_struct&nbsp;structure&nbsp;is&nbsp;declared&nbsp;in&nbsp;include/linux/sched.h&nbsp;and&nbsp;is&nbsp;curren&nbsp;<BR>tly&nbsp;1680&nbsp;bytes&nbsp;in&nbsp;size.&nbsp;<BR>The&nbsp;state&nbsp;field&nbsp;is&nbsp;declared&nbsp;as:&nbsp;<BR>volatile&nbsp;long&nbsp;state;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;-1&nbsp;unrunnable,&nbsp;0&nbsp;runnable,&nbsp;0&nbsp;stopped&nbsp;*/&nbsp;<BR>#define&nbsp;TASK_RUNNING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;<BR>#define&nbsp;TASK_INTERRUPTIBLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;<BR>#define&nbsp;TASK_UNINTERRUPTIBLE&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;<BR>#define&nbsp;TASK_ZOMBIE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;<BR>#define&nbsp;TASK_STOPPED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8&nbsp;<BR>#define&nbsp;TASK_EXCLUSIVE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;32&nbsp;<BR>Why&nbsp;is&nbsp;TASK_EXCLUSIVE&nbsp;defined&nbsp;as&nbsp;32&nbsp;and&nbsp;not&nbsp;16?&nbsp;Because&nbsp;16&nbsp;was&nbsp;used&nbsp;up&nbsp;by&nbsp;TA&nbsp;<BR>SK_SWAPPING&nbsp;and&nbsp;I&nbsp;forgot&nbsp;to&nbsp;shift&nbsp;TASK_EXCLUSIVE&nbsp;up&nbsp;when&nbsp;I&nbsp;removed&nbsp;all&nbsp;refer&nbsp;<BR>ences&nbsp;to&nbsp;TASK_SWAPPING&nbsp;(sometime&nbsp;in&nbsp;2.3.x).&nbsp;<BR>The&nbsp;volatile&nbsp;in&nbsp;p-state&nbsp;declaration&nbsp;means&nbsp;it&nbsp;can&nbsp;be&nbsp;modified&nbsp;asynchronously&nbsp;&nbsp;<BR>(from&nbsp;interrupt&nbsp;handler):&nbsp;<BR>1.&nbsp;TASK_RUNNING&nbsp;means&nbsp;the&nbsp;task&nbsp;is&nbsp;&quot;supposed&nbsp;to&nbsp;be&quot;&nbsp;on&nbsp;the&nbsp;run&nbsp;queue.&nbsp;The&nbsp;rea&nbsp;<BR>son&nbsp;it&nbsp;may&nbsp;not&nbsp;yet&nbsp;be&nbsp;on&nbsp;the&nbsp;runqueue&nbsp;is&nbsp;that&nbsp;marking&nbsp;task&nbsp;as&nbsp;TASK_RUNNING&nbsp;a&nbsp;<BR>nd&nbsp;placing&nbsp;it&nbsp;on&nbsp;the&nbsp;runqueue&nbsp;is&nbsp;not&nbsp;atomic,&nbsp;however&nbsp;if&nbsp;you&nbsp;look&nbsp;at&nbsp;the&nbsp;queu&nbsp;<BR>e&nbsp;under&nbsp;protection&nbsp;of&nbsp;runqueue_lock&nbsp;then&nbsp;every&nbsp;TASK_RUNNING&nbsp;is&nbsp;on&nbsp;the&nbsp;runque&nbsp;<BR>ue.&nbsp;The&nbsp;converse&nbsp;is&nbsp;not&nbsp;true.&nbsp;Namely,&nbsp;drivers&nbsp;can&nbsp;mark&nbsp;themselves&nbsp;(or&nbsp;rather&nbsp;<BR>&nbsp;the&nbsp;process&nbsp;context&nbsp;they&nbsp;run&nbsp;in)&nbsp;as&nbsp;TASK_INTERRUPTIBLE&nbsp;(or&nbsp;UNINTERRUPTIBLE)&nbsp;<BR>&nbsp;and&nbsp;then&nbsp;call&nbsp;schedule()&nbsp;which&nbsp;removes&nbsp;it&nbsp;from&nbsp;the&nbsp;runqueue&nbsp;(unless&nbsp;there&nbsp;i&nbsp;<BR>s&nbsp;a&nbsp;pending&nbsp;signal,&nbsp;in&nbsp;which&nbsp;case&nbsp;it&nbsp;is&nbsp;left&nbsp;on&nbsp;the&nbsp;runqueue).&nbsp;speaking&nbsp;not&nbsp;&nbsp;<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -