基于ARM的智能手持设备MP3播放器的设计与开发 英文参考文献.doc_第1页
基于ARM的智能手持设备MP3播放器的设计与开发 英文参考文献.doc_第2页
基于ARM的智能手持设备MP3播放器的设计与开发 英文参考文献.doc_第3页
基于ARM的智能手持设备MP3播放器的设计与开发 英文参考文献.doc_第4页
基于ARM的智能手持设备MP3播放器的设计与开发 英文参考文献.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

xxx工业大学本科毕业设计外文文献翻译学校代码: xxx学 号: xxx 本科毕业设计外文文献翻译(学生姓名:xxx学 院:信息工程学院系 别:计算机系专 业:软件工程班 级:软件06指导教师:xxx 副教 授二 一 年 六 月10process managementthe process is one of the fundamental abstractions in unix operating systems. a process is a program(object code stored on some media) in execution. processes are, however, more than just the executingprogram code (often called the text section in unix). they also include a set of resources such as open files and pending signals, internal kernel data, processor state, an address space, one or more threads ofexecution, and a data section containing global variables. processes, in effect, are the living result of running program code.threads of execution, often shortened to threads, are the objects of activity within the process. each thread includes a unique program counter, process stack, and set of processor registers. the kernel schedules individual threads, not processes. in traditional unix systems, each process consists of one thread. in modern systems, however, multithreaded programsthose that consist of more than one threadare common. linux has a unique implementation of threads: it does not differentiate between threads and processes. to linux, a thread is just a special kind of process.on modern operating systems, processes provide two virtualizations: a virtualized processor and virtual memory. the virtual processor gives the process the illusion that it alone monopolizes the system, despite possibly sharing the processor among dozens of other processes. discusses this virtualization. virtual memory lets the process allocate and manage memory as if it alone owned all the memory in the system. interestingly, note that threads share the virtual memory abstraction while each receives its own virtualized processor.a program itself is not a process; a process is an active program and related resources. indeed, two or more processes can exist that are executing the same program. in fact, two or more processes can exist that share various resources, such as open files or an address space.a process begins its life when, not surprisingly, it is created. in linux, this occurs by means of the fork()system call, which creates a new process by duplicating an existing one. the process that calls fork() is the parent, whereas the new process is the child. the parent resumes execution and the child starts execution at the same place, where the call returns. the fork() system call returns from the kernel twice:once in the parent process and again in the newborn child.often, immediately after a fork it is desirable to execute a new, different, program. the exec*() family of function calls is used to create a new address space and load a new program into it. in modern linux kernels, fork() is actually implemented via the clone() system call, which is discussed in a followingsection.finally, a program exits via the exit() system call. this function terminates the process and frees all its resources. a parent process can inquire about the status of a terminated child via the wait4() system call, which enables a process to wait for the termination of a specific process. when a process exits, it is placed into a special zombie state that is used to represent terminated processes until the parent calls wait() or waitpid().another name for a process is a task. the linux kernel internally refers to processes as tasks. although when i say task i am generally referring to a process from the kernels point of view.1 process descriptor and the task structurethe kernel stores the list of processes in a circular doubly linked list called the task list. each element in the task list is a process descriptor of the type struct task_struct, which is defined in .the process descriptor contains all the information about a specific process.the task_struct is a relatively large data structure, at around 1.7 kilobytes on a 32-bit machine. this size,however, is quite small considering that the structure contains all the information that the kernel has and needs about a process. the process descriptor contains the data that describes the executing programopen files, the processs address space, pending signals, the processs state, and much more2 allocating the process descriptorthe task_struct structure is allocated via the slab allocator to provide object reuse and cache coloring prior to the 2.6 kernel series, struct task_struct was stored at the end of the kernel stack of each process. this allowed architectures with few registers, such as x86, to calculate the location of the process descriptor via the stack pointer without using an extra register to store the location. with the process descriptor now dynamically created via the slab allocator, a new structure, struct thread_info, was created that again lives at the bottom of the stack and at the top of the stack . the new structure also makes it rather easy to calculate offsets of its values for use in assembly code.the thread_info structure is defined on x86 in asstruct thread_info struct task_struct *task;struct exec_domain *exec_domain;unsigned long flags;unsigned long status;_u32 cpu;_s32 preempt_count;mm_segment_t addr_limit;struct restart_block restart_block;unsigned long previous_esp;_u8 supervisor_stack0;each tasks thread_info structure is allocated at the end of its stack. the task element of the structure is a pointer to the tasks actual task_struct.3 storing the process descriptorthe system identifies processes by a unique process identification value or pid. the pid is a numerical value that is represented by the opaque type pid_t, which is typically an int. because of backward compatibility with earlier unix and linux versions, however, the default maximum value is only 32,768 although the value can optionally be increased to the full range afforded the type. the kernel stores this value as pid inside each process descriptor.this maximum value is important because it is essentially the maximum number of processes that may exist concurrently on the system. although 32,768 might be sufficient for a desktop system, large servers may require many more processes. the lower the value, the sooner the values will wrap around, destroying the useful notion that higher values indicate later run processes than lower values. if the system is willing to break compatibility with old applications, the administrator may increase the maximum value via /proc/sys/kernel/pid_max.inside the kernel, tasks are typically referenced directly by a pointer to their task_struct structure. in fact, most kernel code that deals with processes works directly with struct task_struct. consequently, it is very useful to be able to quickly look up the process descriptor of the currently executing task, which is done via the current macro. this macro must be separately implemented by each architecture. some architectures save a pointer to the task_struct structure of the currently running process in a register, allowing for efficient access. other architectures, such as x86 (which has few registers to waste), make use of the fact that struct thread_info is stored on the kernel stack to calculate the location of thread_info and subsequently the task_struct. on x86, current is calculated by masking out the 13 least significant bits of the stack pointer to obtain the thread_info structure. this is done by the current_thread_info() function. the assembly is shown here:movl $-8192, %eaxandl %esp, %eaxthis assumes that the stack size is 8kb. when 4kb stacks are enabled, 4096 is used in lieu of 8192.finally, current dereferences the task member of thread_info to return the task_struct:current_thread_info()-task; contrast this approach with that taken by powerpc (ibms modern risc-based microprocessor), which stores the current task_struct in a register. thus, current on ppc merely returns the value stored in the register r2. ppc can take this approach because, unlike x86, it has plenty of registers. because accessing the process descriptor is a common and important job, the ppc kernel developers deem using a register worthy for the task.4 process statethe state field of the process descriptor describes the current condition of the process. each process on the system is in exactly one of five different states. this value is represented by one of five flags:(1) task_running the process is runnable; it is either currently running or on a runqueue waiting to run. this is the only possible state for a process executing in user-space; it can also apply to a process in kernel-space that is actively running.(2) task_interruptible. the process is sleeping (that is, it is blocked), waiting for some condition to exist. when this condition exists, the kernel sets the processs state to task_running. the process also awakes prematurely and becomes runnable if it receives a signal.(3) task_uninterruptible this state is identical to task_interruptible except that it does not wake up and become runnable if it receives a signal. this is used in situations where the process must wait without interruption or when the event is expected to occur quite quickly. because the task does not respond to signals in this state, this state is less often used than task_interruptible(4)task_zombie the task has terminated, but its parent has not yet issued a wait4() system call. the tasks process descriptor must remain in case the parent wants to access it. if the parent calls wait4(), the process descriptor is deallocated.(5) task_stopped process execution has stopped; the task is not running nor is it eligible to run. this occurs if the task receives the sigstop, sigtstp, sigttin, or sigttou signal or if it receives any signal while it is being debugged.5 manipulating the current process statekernel code often needs to change a processs state. the preferred mechanism is using set_task_state(task, state); this function sets the given task to the given state. if applicable, it also provides a memory barrier to force ordering on other processors (this is only needed on smp systems). otherwise, it is equivalent to task-state = state; the method set_current_state(state) is synonymous to set_task_state(current, state).6 process contextone of the most important parts of a process is the executing program code. this code is read in from an executable file and executed within the programs address space. normal program execution occurs in userspace. when a program executes a system call or triggers an exception, it enters kernel-space. at this point, the kernel is said to be executing on behalf of the process and is in process context. when in process context, the current macro is valid. upon exiting the kernel, the process resumes execution in user-space, unless a higher-priority process has become runnable in the interim, in which case the scheduler is invoked to select the higher priority process. system calls and exception handlers are well-defined interfaces into the kernel. a process can begin executing in kernel.进程管理进程是uinx操作系统最基本的抽象之一。一个进程就是处于执行期间的程序(目标代码放在某种存储介质上)。但进程并不仅仅局限于一段可执行程序(unix称其为代码段(text section)。通常进程还要包含其他资源,像打开的文件、挂起的信号、内核内部数据、处理器状态、地址空间及一个或多个执行线程、当然还包括用来存放全局变量的数据段等。实际上,进程就是正在执行的程序代码的活标本。执行线程,简称线程(thread),是在进程中活动的对象。每个线程用由一个独立的程序计数器、进程栈和一组进程寄存器。内核调度的对象是线程,而不是进程。在传统的unix系统中,一个进程只包含一个线程,但现在的系统中,包含多个线程的多线程程序司空见惯。linux系统的线程实现非常特别他对线程和进程并不特别区分。对linux而言,线程只不过是一种特殊的进程罢了。在现代操作系统中,进程提供两种虚拟机制:虚拟处理器和虚拟内存。虽然实际上可能是许多进程正在分享一个处理器,但虚拟处理器给进程一种假象,让这些进程觉得自己在独享处理器。而虚拟内存让进程在获取和使用内存是觉得自己拥有整个操作系统的所有内存资源。有趣的是,注意在线程之间(这里是指包含在同一个进程中的进程)可以共享虚拟内存,但拥有各自的虚拟处理器。程序本身并不是进程:进程是处于执行期间的程序以及它所包含的资源的总称。实际上完全可以存在两个或者多个不同的进程执行的是同一个程序。并且两个或两个以上并存的进程还可以共享许多诸如打开的文件、地址空间之类的资源。无疑,进程在它被创建的时刻开始存活。在linux系统中,这通常是调用fork()系统调用的结果,该系统调用通过复制一个现有进程来创建一个全新的进程。调用fork()的进程被称为父子进程,新产生的进程被称为子进程。在调用结束的时,在返回这个相同位置上,父进程恢复执行,子进程开始执行。fork()系统调用从内核返回两次:一次回到父进程,另一个回到新诞生的子进程。通常,创建新的进程都是为了立即执行新的、不同的程序,而接着调用exec()这族函数就可以创建新的地址空间,并把新的程序载入。在现代linux内核中,fork()实际上是由clone()系统调用实现的,后者将在后面讨论。最终,程序通过exit()系统调用退出。这个函数会终结进程并将其占有的资源释放掉。父进程可以通过wait()系统调用查询子进程是否终结,这其实使得进程拥有了等待指定进程执行完毕的能力。进程退出执行后被置为僵死状态,直到它的父进程调用wait()或waitpid()为止。进程的另一个名字是任务(task)。linux内核通常把进程也叫做任务。在这里所说的任务是指从内核观点看到的进程。1 进程描述符及任务结构内核把进程存放在叫做任务队列(task list)的双向循环链表中。链表的每一项都是类型为task_struct、称为进程描述符的结构,改结构定义在文件中。进程描述符中包含一个具体进程的所有信息。task_struct相对较大,在32位机器上,它大约有1.7k字节。但如果考虑到该结构内包含了内核管理一个进程所需要的所有信息,那么它的大小也相当小了。进程描述符中包含的数据能完整的描述一个正在执行的程序:它打开的文件,进程的地址空间,挂起的信号,进程的状态,还有其他更多的信息。2 进程描述符linux通过slab非配器分配task_struct结构,这样能达到对象复用和缓存着色的目的。在2.6以前的内核中,各个进程的task_struct存放在他们的内核栈的尾端。这样做的目的是为了让那些像x86这样寄存器较的硬件体系结构只要通过栈指针就能算出它的位置,从而避免使用额外的寄存器专门记录。由于现在用slab分配器动态生成task_struct,所以只需在栈底或栈顶创建一个新的结构struct thread)info。这个新的结构能使在汇编代码中计算器偏移变得相当的容易。在x86上,thread_info struct task_struct *任务;struct exec_domain *exec_domain;unsigned long flags;unsigned long status;_u32cpu;_s32preempt_count;mm_segment addr_limit;struct restart_blockrestart_block;unsigned longprevious_esp;_u8supervisor_stack0;每个任务的thread_info 结构在它的内核栈的尾端分配。结构中task域中存放的是指向该任务实际task_struct的指针。3 进程描述符的存放内核通过一个唯一的进程标识值或pid来表示每个进程。pid 是一个数,表示为pid_t隐含类型,实际上就是一个int类型。为了老版本的unix和linux兼容,pid 的最大值默认设置为32768,尽管这个值也可以增加到类型所允许的范围。内核把每个进程pid存放在他们各自的进策划那个描述符中。这个值很重要,因为它实际上就是系统中允许同时存在的进程的最大数目。尽管32768对一般的桌面系统足够用了,但是大型服务器可能需要更新进程。这个值越小,转一圈就越快,本类数值大的进程比数值小的进程迟运行,但这样一来就破坏了这一原则。如果确实需要的话,可以不考虑与老式系统的兼容,由系统管理员通过修改/proc/sys/kernel/pid_max来提高上限。 在内核中,访问任务通常需要获得指向其task_struct指针。实际上,内核中大部分处理进程的代码都是直接通过task_struct进行的。因此,通过current宏查找到当前正在运行进程的进程描述符的速度就显得尤为重要。硬件体系结构不同,该宏的实现也就不同,它必须针对专门的硬件体系结构作处理。有的硬件体系结构可以拿出一个专门寄存器来存放指向当前进程task_strcut的指针,用于加快访问速度。而有些像x86这样的体系结构,就只能在内核栈的尾端创建thread_info结构,通

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论