什么叫程序运行?

什么叫程序运行?

  • nakeman联想不断……
    • 2009-4-9 20:04:23 b.用电脑多了会有种错觉,以为计算机屏幕上跑了好多不同的程序,包括也以为操作系统也一个独立运行的程序。事实上,这种不同只存在于不同的应用程序之间,操作系统在逻辑上是应用程序的一部分。如果这种假设成立,那么有个概念很难理解,就是到底什么叫运行?
    • 2009-4-9 21:37:32 b.之所以很理解应用程序和操作系统是“运行”的同一体,是因为操作系统具体双重角色。操作系统在作硬件的扩展一面是与应用程序一同“运行”;在作为资源管理一面则是管理应用程序,有自己的“运行”……
    • 2009-4-10 11:47:37 b.操作系统与应用程序是“运行”的同一体可以从操作系统提供的DLL看出来。这些DLL都是操作系统提供的服务的具体代码,应用程序运行时要将其映射入地址空间,一并“运行”。可“运行”的计算机系统被模块化成很多部分。硬件、系统软件和应用软件是其中最主要的三个部分。
    • 2009-4-11 11:05:30 b.不能理解操作系统与应用程序是“运行”的同一体的另一个原因是,运行指进程内代码是直接调用,而操作系统与应用程序的代码不全是运行在同一个地址空间中,也就是说操作系统给应用程序提供的服务是独立运行的进程,应用程序与服务进程通过进程同步的方式一并“运行”。
    • 2009-4-21 17:45:41 b.原来“运行”的概念就是进程的概念!不过进程的定义——进程是程序的一次执行——在多道程序的环境下也不太好理解。因为不太清楚“运行”的确切涵义,从而不能把握多进程多线程分隔的本质。
    • 2009-4-21 18:01:19 b.要理解“运行”的确切涵义关键在运行的需要的环境,理解“运行”到底完成什么任务。比如,进程任务是计算集中的还是数据处理集中的?如果是计算集中的,像进程调度器,那么调度器的多线程的可能性比较低了;如果是数据处理集中的,比如下载工具,下载子任务完全可以并行“运行”。
    • 2009-4-21 18:14:41 b.我们似乎来到了理解“运行”的一个关键点了。就是得把“计算任务”解开。从上面可知,很明显是“计算任务”的性质决定了线程是否可以并行运行。“计算任务”其实就是我们设计一个软件程序的初衷和目的。但是在我们完全理解计算机是如何工作来完成这些“任务”之前,“计算任务”很难解开。
    • 2009-4-21 19:23:37 b.显然“计算任务”种类繁多,大概可以分为计算集中和数据处理集中两类,而它们都可说成是信息处理。我们第一印象,计算机完成这些任务利用了计算硬件资源,比如CPU、内存和IO设备;CPU显然已经够复杂的了,但是建立在内存和IO设备之的软件资源更复杂!
    • 2009-4-22 17:27:03 b.多线程编程意味着什么?怎么没有多进程编程?要理解这两只须想想什么叫创建一个新进程或创建一个新线程就明白了。进程一般只管自己的计算任务,它自己被创建是操作系统的计算任务,从在内存中创建一个新进程或线程可以看出来(如线程控制块数据结构)。所以多线程编程是为了提高程序效率开了一扇侧门给程序员使用操作系统功能;而多进程则算是病毒行为了。我现在不明白的是,多线程如何可能?进程间有互斥资源,难道线程间没有吗?
    • 2009-4-22 18:15:28 b.缺乏软件开发经验的人把“计算任务”看得太纯一,所以很难理解多线程如何可能。现代软件功能远不是过去以计算为主的了(其实即使是算法任务也有可能并行,比如动态规划算法),一个简单的例子,程序的GUI部分与用户交互的同时,后台可进行网络数据传输或其它计算任务。
    • 2009-4-22 21:28:03 b.处理器调度工作内容分两种!为什么呢?因为显然,进程内的线程切换与进程间的线程切换是不同的,后者也叫进程切换。书上说:“Linux中进程和线程都有独立的PCB结构,线程共享进程的代码段、数据段,线程有自己的堆栈和私有数据段。 ”,对了吧,调度进程使用两种PCB结构进行调度工作。P.S.这里很有意思的是,处理器通过调度进程对“自己”进行调度。
    • 2009-4-23 1:01:05 b.来分析一下“处理器通过调度器对自己进行调度”这个悖。其实这个也像罗素提出的理发师的悖,演绎推理中出现跨层次范畴而造成的。CPU是不知道什么叫调度,更不知道什么线程切换。CPU只会读PC寄存器后一条一条指令顺序执行。现代CPU开了中断这扇后门(这样可以改变CPU的执行路线)给系统开发者进行各种演绎,包括上面所说的调度、上下文切换等。举一个例子,进程调度开始于一个时钟中断,CPU接到这个中断转到约定的地址执行时钟中断处理程序—— 调度器,调度器经过调度算法选中一个新的线程进入,判断如果是进程内线程则进行线程上下文切换并执行,否则进行进程上下文切换。这里边与其说是CPU调度自己,不如说是调度器把自己调出给新的线程占用CPU。
    • 2009-4-23 12:22:45 b.上下文切换是调度器的任务之一,但不是只有调试器才会进行上下文切换。比如线程在调用系统服务时进行的上下文切换(这个切换与进程或线程上下文切换都有不同)。我现在特想知道的是,调度算法的详细和具体的各种上下文切换过程详细。
    • 2009-4-23 12:44:18 b.上下文切换是多道程序的特征和必要。但是有一种切换迷惑了我们,就是协作式任务的切换,比如系统服务调用和硬件驱动调用。细心想想,其实切换的本质是换工作内容。由WORD切换到音乐播放器是进程切换;由WORD里的拼写检查到接受用户输入的切换是线程切换。而由音乐播放器解码到声卡驱动将解码数据输出的切换则是一种伪切换,它是一个无法分解的任务前后部分,但是因为要对硬件的保护而做成客户服务形式。这个过程中,音乐播放器的主线程被挂起,而声卡驱动输出可能不需要音乐播放器的主线程的任何信息(这就是所谓的无关上下文任务),完成后就绪(具体可能置一下音乐播放器的主线程某状态位)音乐播放器的主线程等待再被调度执行……

什么是线程状态?

  • 当提及一个例程的上下文时,我们是指它的线程和进程的执行环境。在NT中,这个环境由当前的线程环境块(TEB)和进程环境块(PEB)建立。上下文因此包括虚拟内存的设置(告诉我们那个物理内存页面对应那个虚拟内存地址),句柄转换(因为句柄是基于进程的),分派器信息,堆栈,以及通用和浮点寄存器的设置。
  • Each thread maintains an independent program counter and hardware context that includes a private set of CPU registers.

线程上下文(Thread Context)

(摘自:http://www.win32asm.com.cn/view.asp?file=320

在大多数情况下,我们的系统中只安装了一个CPU,所以,对于所有这些运行中的程序来说,操作系统对每个进程中的线程所使用的CPU时间进行调度,循环为每个线程分配时间片,这就造成了多个程序同时执行的假象。如果Windows检测到一个新线程要开始运行了,它将进行一次上下文切换(context switch)(注:”上下文“ 实际上就是线程运行的环境,也就是运行时各寄存器和其他东东的状态,更自然的理解就是"线程状态")。所谓上下文切换就是保存线程运行时的机器状态,然后将另一个线程的状态恢复并重新开始执行。如果重新开始执行的线程属于另一个进程,那么该进程的地址空间也将被同时切换过来(通过在CR3寄存器中装入页表)。

AMD and Intel x86 CPU Architecture - System Registers

每个用户进程都有私有的地址空间,所以他们的页表都是不同的,CPU通过切换页表来将虚拟地址映射到物理地址,设备驱动程序并不需要直接做这些工作。上下文切换比较耗CPU时间,所以驱动程序一般不创建它们自己的线程,它们一般在下列环境中的一个中运行:

  • 1. 在发起I/O请求的用户线程中运行
  • 2. 在内核模式下的系统线程中运行
  • 3. 作为中断运行(并不处于哪个特定的进程或线程中,因为它们都被暂时挂起了)

在处理I/O请求包(IRPs)时,我们总是运行在和用户模式的调用者相同的进程上下文中运行,这样我们就能对用户程序的地址空间进行寻址。但是当驱动程序被加载或者卸载的时候,我们将在系统进程中运行,这时存取的只能是系统的地址空间。

内核代码是怎么被执行的?

(翻译自《Windows 2000 Device Driver Book a Guide for Programmers》BY Art Baker / Jerry Lozano

The kernel-mode parts of Windows 2000 (including a device driver) consist of massive(厚重的, 大块的) amounts of code. But just what causes this code to execute? All code executes within a hardware and software context. A context, as used here, describes the state of the system while a CPU instruction executes. It includes the state of all CPU registers (including the stack), the processor mode (user or kernel), and significantly, the state of the hardware page tables. This last item describes what memory can be seen by executing code, and where within the address space that memory is located.

Windows 2000的内核(在CPU核态运行的、包括驱动程序代码)由成千上万行代码组成,有没有想过到底是由谁来主导这些代码运行的呢?代码都是在一定的软件和硬件的上下文中执行的。这里的上下文指的是当CPU执行一条指时系统的状态,包括所有CPU寄存的状态(包当前的堆栈)、CPU的操作模式(用户或核心的)和硬件页表(hardware page tables?)的状态。硬件页表包含两项内容,一个是指出被执行代码可见的内存范围,一个是这些内存所在的地址空间。

Clearly, code must make assumptions about the context in which it executes. Windows 2000 defines three execution contexts for kernel-mode execution. In other words, kernel-mode driver code executes in one of three contexts.

一般的用户进程不会有很明显的对上下文的意识,因为用户进程运行的角色单一,只有一个默认的上下文。而操作系统则不同,它有三种角色,为用户进程服务,为硬件请求服务,为自己服务。所以,操作系统的内核代码运行在三种上下文之间。

Trap or Exception Context

Chapter 1 described how user-mode code can request an OS service by trapping into kernel mode. When a kernel-mode routine executes, it may be because a user-mode application or service caused a hardware or software exception, or trap, to occur. In this case, the context of the kernel-mode code is largely that of the user code that caused the exception. The memory seen by kernel-mode code includes the same view as seen by the requesting user-mode thread.

第一章讲了用户模式代码是如何通过陷入内核模式来使用系统服务的。当用户模式代码引发一个软件中断或其它方式调用系统服务时,内核代码被执行。这时,内核代码的上下文是用户模式代码的上下文。例如,当用户线程向I/O管理器请求服务时,I/O管理器就是运行在用户线程的上下文。而I/O管理器一般这把这个请求转交给设备驱动,所以设备驱动程序运行在用户线程的上下文。

When a user-mode thread makes a direct request of the I/O Manager, the I/O Manager executes within the context of the requester. In turn, the I/O Manager may call a dispatch routine within a device driver. Dispatch routines of a driver therefore execute within this exception context.

Interrupt Context

When the hardware (or software) generates an acknowledged(承认; 告知收到; 对...打招呼; 答谢 ) interrupt, whatever code is executing within the system is stopped dead in its tracks. The executing context is saved and control is promptly(敏捷地; 迅速地 ) handed over to a service routine appropriate for the kind of interrupt that occurred.

当硬件(或软件)产生的中断请求得到响应时,CPU进入中断处理的上下文。中断处理的上下文与被打断的代码上下文一般是不相干的。中断请求的服务代码不对页表作任何假设(KEMIN:因为不会用到?)。用户模式的缓冲存储器(buffers)在中断处理的上下文必须是不可用的。运行在中断处理的上下文的代码(包括硬件驱动代码)也不对当前进程作任何假设。

Clearly, the context of the executing code at the time of the interrupt is irrelevant and arbitrary. Kernel-mode code servicing the interrupt cannot make any assumptions about the state of the page tables. User-mode buffers must be considered unavailable in this context. Code running in interrupt context (which includes the bulk of driver routines) can make no assumptions about the current process or thread.

Kernel-Mode Thread Context

The final possibility is that a piece of code runs in the context of a separate kernel thread. Some drivers spawn separate threads to deal with devices that require polling or to deal with specialized timeout conditions. These kernel-mode threads are not significantly different from user-mode threads described in Win32 programming books. They execute when scheduled by the kernel's scheduler, in accordance with the assigned thread priority.

最后一种是内核线程独立拥有的上下文。有一些驱动程序需要一些独立的辅助线程来处理那些需要轮询访问或处理超时的设备。作为一种线程,内核线程其实与用户线程区别并不大,它们也像用户线程一样被内核调度器进行调度运行。

Like the interrupt context, kernel-mode thread context can make no assumption about the current process or thread. The state of the page tables is largely arbitrary as seen by the thread. Chapter 14 discusses the use of kernel-mode threads.

不过内核线程执行的上下文与中断处理的上下文类似,不对当前进程作任何假设。(KEMIN:总的来说,内核线程是有点怪,这样理解吧,如果用户线程和中断服务分别完成不同性质的任务的话,内核线程介它们之间完成另一任务,嗯,任务任务,很好!)

参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值