同一进程下的多个线程可以共享以下资源:
进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。
1、什么是临界区?
答:每个进程中访问临界资源的那段程序称为临界区(临界资源是一次仅允许一个进程使用的共享资源)。每次只准许一个进程进入临界区,进入后不允许其他进程进入。
2、进程进入临界区的调度原则是:
①如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入。②任何时候,处于临界区内的进程不可多于一个。如已有进程进入自己的临界区,则其它所有试图进入临界区的进程必须等待。③进入临界区的进程要在有限时间内退出,以便其它进程能及时进入自己的临界区。④如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。
1 )互斥信号量初值为 1 ,变化范围为[ -n + l , 1 ]。
当没有进程进入互斥段时,信号量值为 1 ;当有 1 个进程进入互斥段但没有进程等待进入互斥段时,信号量值为 0 ;当有 1 个进程进入互斥段且有一个进程等待进入互斥段时,信号量值为-1 ;最多可能有 n -1 个进程等待进入互斥段,故此时信号量的值应为 - ( n - 1 )也就是 -n+1。
2 )互斥信号量初值为 m ,变化范围为[ -n + m , m ]。
当没有进程进入互斥段时,信号量值为 m ;当有 1 个进程进入互斥段但没有进程等待进入互斥段时,信号量值为 m - 1 :当有 m 个进程进入互斥段且没有一个进程等待进入互斥段时,信号量值为 0 :当有 m 个进程进入互斥段且有一个进程等待进入互斥段时,信号量值为 - 1 ;最多可能有 n - m 个进程等待进入互斥段,故此时信号量的值应为 -(n-m) 也就是 -n+m
IOCTL 方法:应用程序分配共享内存
在用户模式与核心模式之间共享内存的最简单有效的方法是使用 IOCTL。IOCTL 有四种不同的类型,下列三种 IOCTL 使您可以在设备驱动程序中直接访问用户缓冲区:
METHOD_IN_DIRECT
METHOD_OUT_DIRECT
METHOD_NEITHER
在以上这些方法中没有创建中间系统缓冲区。
METHOD_IN_DIRECT 和 METHOD_OUT_DIRECT 自动在 DeviceIoControl 中锁定用户指定的缓冲区,并为驱动程序创建内存描述列表 (MDL)。驱动程序可以从 MDL 得到一个系统地址,并根据 IOCTL 传输类型将信息传入传出缓冲区。由于所有的缓冲区验证、锁定及 MDL 创建均是通过 I/O 管理器来完成的,所以这是一种简单的方法。
相反,METHOD_NEITHER 直接将用户缓冲区提供给驱动程序,驱动程序必须适当地验证缓冲区并锁定缓冲区,如果需要,还要为缓冲区获取一个系统地址。虽然这是通过设备驱动程序 I/O 子系统的最快捷路径,但使用这种方法时也有一些应当注意的问题。有关其它信息,请参见 Microsoft Knowledge Base 中的下列文章:
Q126416 INFO:使用 METHOD_NEITHER IOCTL 的警告
要了解这三种不同的 IOCTL 如何工作,请参见以下 Microsoft Knowledge Base 文章:
Q178317 文件:IOCTLexe:如何使用不同类型的 IOCTL
MmMapLockedPages 方法:设备驱动程序分配共享内存
在这种方法中,驱动程序通过 MmAllocateContiguousMemory 或 ExAllocatePoolXxx 函数分配内存,创建并建立描述缓冲区的 MDL,并使用 MmMapLockedPages 把内存映射到用户进程地址空间中。用户应用程序可以使用由 MmMapLockPages 返回的虚拟地址直接访问系统内存。
由于应当在访问内存的进程上下文中完成映射,所以此方法只能用于单层结构的驱动程序,这时可以保证 dispatch 例程在调用进程上下文中运行。您可以在任意数量的用户过程地址空间上映射同一个系统缓冲区。不过,应当设计一种保护机制,使驱动程序及所有应用程序对内存的访问同步。进一步说,应当在终止进程之前或者一旦使用完缓冲区就在映射缓冲区的相同进程上下文中取消缓冲区的映射。下面介绍将驱动程序缓冲区映射至某个用户进程时需采取的步骤:
首先如下分配内存:
SystemVirtualAddress = MmAllocateContiguousMemory(NumberOfBytes,
HighestAcceptableAddress); 或
SystemVirtualAddress = ExAllocatePool(PoolType, NumberOfBytes);
如下分配一个 MDL:
Mdl = IoAllocateMdl(SystemVirtualAddress, NumberOfBytes, FALSE,
FALSE, NULL);
建立 MDL 以描述内存页。如果已经分配了非页面缓冲池中的内存,请使用:
MmBuildMdlForNonPagedPool(Mdl);
如果分配了页面缓冲池中的内存,请使用:
MmProbeAndLockPages(Mdl, KernelMode, IoWriteAccess);
如下将锁定的页面映射至进程的用户地址空间中:
UserVirtualAddress = MmMapLockedPages(Mdl, UserMode);
前三步可以在 DriverEntry 或 Dispatch 例程中完成。但是,将缓冲区映射至用户地址空间的最后一步,应当在运行于调用进程上下文的某个例程(通常是单层驱动程序的 dispatch 例程)中完成。
您可以在某个提高的 IRQL 级及任何进程上下文(即中断服务例程 (ISR) 及延迟过程调用 (DPC))的驱动程序中使用 SystemVirtualAddress,在应用程序或运行正确进程上下文的驱动程序中使用 UserVirtualAddress。
按照下列步骤取消映射并释放缓冲区:
首先从用户地址空间中取消页面映射。应在映射 UserVirtualAddress 的进程上下文中运行时调用函数:
MmUnmapLockedPages(UserVirtualAddress, Mdl);
如果使用 MmProbleAndLockPages 锁定了页面,则使用以下函数解锁:
MmUnlockPages(Mdl)
释放 MDL:
IoFreeMdl(Mdl);
释放系统内存:
MmFreeContiguousMemory(SystemVirtualAddress); 或
ExFreePool(SystemVirtualAddress);
共享内存对象方法
使用保存在页面文件上的内存映射文件是用于在用户进程之间共享内存的常用方法。不过,您可以使用以上技术在用户过程及设备驱动程序之间共享内存。使用这种技术有两种方法。在第一种方法中,驱动程序可以创建命名内存对象(称为 section 对象),一个或多个应用程序通过使用 OpenFileMapping 打开以上对象,然后调用 MapViewOfFile 函数来得到指向它的指针。通过指定以上对象的保护属性,可以定义某个进程使用内存的方式。
在第二种方法中,应用程序可以使用 CreateFileMapping 在用户模式下创建一个命名内存对象。驱动程序通过使用 ZwMapViewOfSection 函数及调用 ZwMapViewOfSection 得到其指针来打开以上内存对象。您应当使用异常处理程序在核心模式中访问该内存地址。有关使用这种技术的范例,请参见下列 Microsoft Knowledge Base 文章:
Q194945 样例:有关在核心和用户模式之间共享内存的 Sectionexe
因为总是在进程的用户地址空间(小于 0x80000000,不管是在核心模式还是在用户模式中创建对象)上映射对象,所以只在进程上下文中访问地址时地址才有效。在相同内存对象上对 MapViewOfFile 或 ZwMapViewOfSection 的每次调用将返回一个不同的内存地址,即使对于相同的进程也是如此。通常不建议使用这种方法,特别是对于低级设备驱动程序而言。如前所述,这是因为地址范围被限制于映射对象的进程中,不能在 DPC 或 ISR 中访问。而且,在核心模式中创建内存对象的 API 没有记载于 DDK 中。
然而,要在提高的 IRQL (如 DPC 或 ISR)上使用该地址,您一定要查明并锁定缓冲区页面,并得到如 IOCTL 方法中所述的系统虚拟地址 (MmGetSystemAddressForMdl)。
只有准备在两个(或多个)用户进程和一个(或多个)设备驱动程序之间共享内存时,这种方法才比较简单容易。否则,使用 IOCTL 技术在一个用户过程及一个设备驱动程序之间共享内存将更为简单有效。
D:1----[-(n-1)]信号量初值为1.当有进程运行时,其他进程访问信号量,信号量就会减一。
信号量是指同时需要多个资源且每种占用一个资源时的信号量 *** 作。即在一个原语中申请整段代码度需要的多个临界资源,要么全部分配给它,要么一个都不分配给它。
以避免当一段处理代码需要同时获取两个或多个临界资问源时,出现由于各进程等待其余的临界资源,变成死锁的情况。
扩展资料:
注意事项:
信号响应,每个信号的顺序并不重要,虽然会影响块队列的过程,但由于原子 *** 作模式,是否所有分配的资源分配,所以总有一个过程的所有资源和释放资源推动后,所以它不会死锁。
由于在信号量和信号量中使用通用信号的灵活性,Swait和Ssignal通常不成对使用。为了避免死锁,可以一起申请所有需要的资源,但不要一起释放它们。
信号量是指进程在执行任务之前需要获取两个或多个共享资源的应用程序。
假设现在有两个进程A和B,它们都需要访问共享数据D和e。当然,共享数据应该始终是关键资源。
为此可以将信号量Dmutex和Emutex分别设置为互斥,并将它们的初始值设置为1,因此个进程都包含了对Dmutex和Emutex的 *** 作。
16个
若系统中有5个进程共享若干个资源R,每个进程都需要4个资源R
此时只要在加一个资源可以使5个进程中的任何一个进程得到满足。即15+1=16
临界资源是指每次仅允许一个进程访问的资源。 属于临界资源的硬件有打印机、磁带机等,软件有消息缓冲队列、变量、数组、缓冲区等。 诸进程间应采取互斥方式,实现对这种资源的共享。 每个进程中访问临界资源的那段代码称为临界区
以上就是关于同一进程下的多个线程可以共享哪一种资源全部的内容,包括:同一进程下的多个线程可以共享哪一种资源、多个进程共享临界区,需遵循的调度原则、设有几个进程共享一互斥段,对于以下两种情况等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)