【发布时间】:2011-02-19 23:07:20
【问题描述】:
假设我在 VC++ 中实现了一个临界区并保护了一些数组,我该如何在 VC++ 中使用锁呢?
【问题讨论】:
标签: windows multithreading winapi visual-c++ locks
假设我在 VC++ 中实现了一个临界区并保护了一些数组,我该如何在 VC++ 中使用锁呢?
【问题讨论】:
标签: windows multithreading winapi visual-c++ locks
你需要critical sections的API函数:
InitializeCriticalSection 从任何线程(但通常是主线程)调用一次以初始化锁。在对它进行任何其他操作之前进行初始化。EnterCriticalSection 从任何线程调用以获取锁。如果另一个线程拥有锁,它将阻塞,直到它可以获取锁。关键部分是可重入的,这意味着线程成功获取锁,即使它已经持有它。LeaveCriticalSection 释放锁。对EnterCriticalSection 的每次调用都必须与对LeaveCriticalSection 的匹配调用配对。不要让异常阻止这些获取/释放调用配对。DeleteCriticalSection 从任何线程(通常是主线程)调用一次,以完成锁定。当没有线程持有锁时执行此操作。调用此方法后,锁无效,您无法再次尝试获取它。MSDN 提供了一个 trivial example.
如果您使用 MFC,那么您可能会使用 CCriticalSection,它将 Win32 临界区 API 封装在一个类中。
至于你如何用你的数组来做这件事。好吧,您的线程一次只会执行受锁保护的代码块。您需要锁定来停止两个线程同时尝试读取/写入同一内存位置的竞争条件,或者实际上可能破坏您的算法的其他更微妙的条件。
如果你要描述数组、它的内容以及你如何操作它,那么可能会给你一些具体的建议。你在这个数组上的具体操作方式将对理想的同步策略产生很大影响,在某些情况下你可以使用无锁方法。
【讨论】:
通过CreateMutex 创建一个互斥锁,通过WaitForSingleObject 获取它的所有权,通过ReleaseMutex 释放互斥锁的所有权,并在完成CloseHandle 后将其删除。
您可以查找的替代方案包括 CriticalSections、Semaphores 和 Events。
【讨论】:
如果您使用的是 VS 2010,则 criticial_section 对象包含在头文件 ppl.h 中。
请注意,还有一个 concurrent_vector 类模板,它是同步的(即不需要锁)。
【讨论】:
critical_section 类是并发运行时的一部分,而不是直接的 Win32 并且不可重入。这些很重要。