fbpx
维基百科

臨界區段

在同步的程式設計中,臨界區段Critical section)或稱為关键区段 ,指的是一個存取共用資源(例如:共用裝置或是共用記憶體)的程式片段,而這些共用資源又無法同時被多個執行緒存取的特性。

當有執行緒進入臨界區段時,其他執行緒或是行程必須等待(例如:bounded waiting 等待法),有一些同步的機制必須在臨界區段的進入點與離開點實現,以確保這些共用資源是被互斥或的使用,例如:semaphore

只能被單一執行緒存取的裝置,例如:印表機

一個最簡單的實現方法就是當執行緒(Thread)進入臨界區段時,禁止改變處理器;在Single-Processor系統上,可以用「禁止中斷(CLI)」來完成,避免发生系统调用(System Call)导致的上下文交換(Context switching);當離開臨界區段時,處理器回復原先的狀態。

Windows操作系统的临界区

Windows操作系统,CRITICAL_SECTION是一种同步对象类型,用于同一个进程内的多线程同步访问资源。如果是跨进程同步,需要使用互斥锁(mutex)。

临界区对象首先需要初始化,通过调用操作系统API函数InitializeCriticalSection。各个线程调用函数 EnterCriticalSection, TryEnterCriticalSection, 或LeaveCriticalSection来使用临界区。使用结束后或者重初始化临界区之前,需要调用 DeleteCriticalSection 。

WINNT.H中定义的临界区数据结构如下:

struct RTL_CRITICAL_SECTION { PRTL_CRITICAL_SECTION_DEBUG DebugInfo; LONG LockCount; LONG RecursionCount; HANDLE OwningThread; HANDLE LockSemaphore; ULONG_PTR SpinCount; }; 

结构的各域的解释:

  • DebugInfo 此字段为一个指针,指向系统分配的结构RTL_CRITICAL_SECTION_DEBUG。这一结构中包含更多极有价值的信息,也定义于 WINNT.H 中。
  • LockCount 被初始化为数值 -1;此数值等于或大于 0 时,表示此临界区被占用。当其不等于 -1 时,OwningThread 字段包含了拥有此临界区的线程 ID。此字段与 (RecursionCount-1) 数值之间的差值表示有多少个其他线程在等待获得该临界区。
  • RecursionCount 初始值为0. 此字段包含所有者线程已经获得该临界区的次数。如果该数值为零,下一个尝试获取该临界区的线程将会成功。
  • OwningThread 此字段包含当前占用此临界区的线程的线程标识符(应为DWORD而不是HANDLE)。此线程 ID 与 GetCurrentThreadId 之类的 API 所返回的 ID 相同。
  • LockSemaphore 是一个自复位的Event内核对象句柄。首次发生线程申请该临界区被阻止时,操作系统自动创建该句柄。应当调用 DeleteCriticalSection(它将发出一个调用该事件的 CloseHandle 调用,并在必要时释放该调试结构),否则将会发生资源泄漏。
  • SpinCount 仅用于多处理器系统。MSDN文档:“在多处理器系统中,如果该临界区不可用,调用线程将在对与该临界区相关的信号执行等待操作之前,旋转 dwSpinCount 次。如果该临界区在旋转操作期间变为可用,该调用线程就避免了等待操作。”自旋计数可以在多处理器计算机上提供更佳性能,其原因在于在一个循环中自旋通常要快于进入内核模式等待状态。此字段默认值为零,但可以用InitializeCriticalSectionAndSpinCount API 将其设置为一个不同值。

RTL_CRITICAL_SECTION_DEBUG结构如下: struct _RTL_CRITICAL_SECTION_DEBUG {

 WORD Type; WORD CreatorBackTraceIndex; RTL_CRITICAL_SECTION *CriticalSection; LIST_ENTRY ProcessLocksList; DWORD EntryCount; DWORD ContentionCount; DWORD Spare[ 2 ]; 

} 结构的各域的解释:

  • Type 此字段未使用,被初始化为数值 0。
  • CreatorBackTraceIndex 此字段仅用于诊断情形中。在注册表项 HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\YourProgram 之下是 keyfield、GlobalFlag 和 StackTraceDatabaseSizeInMb 值。注意,只有在运行稍后说明的 Gflags 命令时才会显示这些值。这些注册表值的设置正确时,CreatorBackTraceIndex 字段将由堆栈跟踪中所用的一个索引值填充。在 MSDN 中搜索 GFlags 文档中的短语“create user mode stack trace database”和“enlarging the user-mode stack trace database”。
  • CriticalSection 指向与此结构相关的 RTL_CRITICAL_SECTION
  • ProcessLocksList: LIST_ENTRY 是用于表示双向链表中节点的标准 Windows 数据结构。RTL_CRITICAL_SECTION_DEBUG 包含了链表的一部分,允许向前和向后遍历该临界区。Flink=NULL为表头,Blink=NULL为表尾
  • EntryCount/ContentionCount 这些字段在相同的时间、出于相同的原因被递增。这是不能获得临界区而进入等待状态的线程的数目。与 LockCount 和 RecursionCount 字段不同,这些字段永远都不会递减。
  • Spares 这两个字段未使用,甚至未被初始化。

外部連結

MSDN Library -- Critical section (页面存档备份,存于互联网档案馆

臨界區段, 此條目需要补充更多来源, 2018年3月13日, 请协助補充多方面可靠来源以改善这篇条目, 无法查证的内容可能會因為异议提出而被移除, 致使用者, 请搜索一下条目的标题, 来源搜索, 网页, 新闻, 书籍, 学术, 图像, 以检查网络上是否存在该主题的更多可靠来源, 判定指引, 在同步的程式設計中, critical, section, 或稱為关键区段, 指的是一個存取共用資源, 例如, 共用裝置或是共用記憶體, 的程式片段, 而這些共用資源又無法同時被多個執行緒存取的特性, 當有執行緒進入時, 其他執. 此條目需要补充更多来源 2018年3月13日 请协助補充多方面可靠来源以改善这篇条目 无法查证的内容可能會因為异议提出而被移除 致使用者 请搜索一下条目的标题 来源搜索 臨界區段 网页 新闻 书籍 学术 图像 以检查网络上是否存在该主题的更多可靠来源 判定指引 在同步的程式設計中 臨界區段 Critical section 或稱為关键区段 指的是一個存取共用資源 例如 共用裝置或是共用記憶體 的程式片段 而這些共用資源又無法同時被多個執行緒存取的特性 當有執行緒進入臨界區段時 其他執行緒或是行程必須等待 例如 bounded waiting 等待法 有一些同步的機制必須在臨界區段的進入點與離開點實現 以確保這些共用資源是被互斥或的使用 例如 semaphore 只能被單一執行緒存取的裝置 例如 印表機 一個最簡單的實現方法就是當執行緒 Thread 進入臨界區段時 禁止改變處理器 在Single Processor系統上 可以用 禁止中斷 CLI 來完成 避免发生系统调用 System Call 导致的上下文交換 Context switching 當離開臨界區段時 處理器回復原先的狀態 Windows操作系统的临界区 编辑在Windows操作系统 CRITICAL SECTION是一种同步对象类型 用于同一个进程内的多线程同步访问资源 如果是跨进程同步 需要使用互斥锁 mutex 临界区对象首先需要初始化 通过调用操作系统API函数InitializeCriticalSection 各个线程调用函数 EnterCriticalSection TryEnterCriticalSection 或LeaveCriticalSection来使用临界区 使用结束后或者重初始化临界区之前 需要调用 DeleteCriticalSection WINNT H中定义的临界区数据结构如下 struct RTL CRITICAL SECTION PRTL CRITICAL SECTION DEBUG DebugInfo LONG LockCount LONG RecursionCount HANDLE OwningThread HANDLE LockSemaphore ULONG PTR SpinCount 结构的各域的解释 DebugInfo 此字段为一个指针 指向系统分配的结构RTL CRITICAL SECTION DEBUG 这一结构中包含更多极有价值的信息 也定义于 WINNT H 中 LockCount 被初始化为数值 1 此数值等于或大于 0 时 表示此临界区被占用 当其不等于 1 时 OwningThread 字段包含了拥有此临界区的线程 ID 此字段与 RecursionCount 1 数值之间的差值表示有多少个其他线程在等待获得该临界区 RecursionCount 初始值为0 此字段包含所有者线程已经获得该临界区的次数 如果该数值为零 下一个尝试获取该临界区的线程将会成功 OwningThread 此字段包含当前占用此临界区的线程的线程标识符 应为DWORD而不是HANDLE 此线程 ID 与 GetCurrentThreadId 之类的 API 所返回的 ID 相同 LockSemaphore 是一个自复位的Event内核对象句柄 首次发生线程申请该临界区被阻止时 操作系统自动创建该句柄 应当调用 DeleteCriticalSection 它将发出一个调用该事件的 CloseHandle 调用 并在必要时释放该调试结构 否则将会发生资源泄漏 SpinCount 仅用于多处理器系统 MSDN文档 在多处理器系统中 如果该临界区不可用 调用线程将在对与该临界区相关的信号执行等待操作之前 旋转 dwSpinCount 次 如果该临界区在旋转操作期间变为可用 该调用线程就避免了等待操作 自旋计数可以在多处理器计算机上提供更佳性能 其原因在于在一个循环中自旋通常要快于进入内核模式等待状态 此字段默认值为零 但可以用InitializeCriticalSectionAndSpinCount API 将其设置为一个不同值 RTL CRITICAL SECTION DEBUG结构如下 struct RTL CRITICAL SECTION DEBUG WORD Type WORD CreatorBackTraceIndex RTL CRITICAL SECTION CriticalSection LIST ENTRY ProcessLocksList DWORD EntryCount DWORD ContentionCount DWORD Spare 2 结构的各域的解释 Type 此字段未使用 被初始化为数值 0 CreatorBackTraceIndex 此字段仅用于诊断情形中 在注册表项 HKLM Software Microsoft Windows NT CurrentVersion Image File Execution Options YourProgram 之下是 keyfield GlobalFlag 和 StackTraceDatabaseSizeInMb 值 注意 只有在运行稍后说明的 Gflags 命令时才会显示这些值 这些注册表值的设置正确时 CreatorBackTraceIndex 字段将由堆栈跟踪中所用的一个索引值填充 在 MSDN 中搜索 GFlags 文档中的短语 create user mode stack trace database 和 enlarging the user mode stack trace database CriticalSection 指向与此结构相关的 RTL CRITICAL SECTION ProcessLocksList LIST ENTRY 是用于表示双向链表中节点的标准 Windows 数据结构 RTL CRITICAL SECTION DEBUG 包含了链表的一部分 允许向前和向后遍历该临界区 Flink NULL为表头 Blink NULL为表尾 EntryCount ContentionCount 这些字段在相同的时间 出于相同的原因被递增 这是不能获得临界区而进入等待状态的线程的数目 与 LockCount 和 RecursionCount 字段不同 这些字段永远都不会递减 Spares 这两个字段未使用 甚至未被初始化 外部連結 编辑MSDN Library Critical section 页面存档备份 存于互联网档案馆 取自 https zh wikipedia org w index php title 臨界區段 amp oldid 70081450, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。