使用 MS Visual C++2012
一个类有一个std::atomic_flag
类型的成员
class A {
public:
...
std::atomic_flag lockFlag;
A () { std::atomic_flag_clear (&lockFlag); }
};
有一个类型A的对象
A object;
谁可以被两个(Boost)线程访问
void thr1(A* objPtr) { ... }
void thr2(A* objPtr) { ... }
如果对象正在被另一个线程访问,想法是等待线程。
问题是:是否有可能用atomic_flag
对象构造这样的机制?暂时不说,我想要一些轻量级的 boost::mutex。
顺便说一下,其中一个线程中涉及的进程是对获得许多行的 dBase 的非常长的查询,我只需要将它暂停在发生冲突的特定代码区域(处理每一行时),然后我不能等待整个线程完成 join()
。
我已经在每个线程中尝试了一些:
thr1 (A* objPtr) {
...
while (std::atomic_flag_test_and_set_explicit (&objPtr->lockFlag, std::memory_order_acquire)) {
boost::this_thread::sleep(boost::posix_time::millisec(100));
}
... /* Zone to portect */
std::atomic_flag_clear_explicit (&objPtr->lockFlag, std::memory_order_release);
... /* the process continues */
}
但没有成功,因为第二个线程挂起。其实我对atomic_flag_test_and_set_explicit
函数中涉及的机制并不完全理解。如果这样的函数立即返回或者可以延迟直到可以锁定标志。
对于我来说,如何使用这样一个总是设置值并返回先前值的函数来获得锁定机制也是一个谜。没有仅读取实际设置的选项。
欢迎提出任何建议。
最佳答案
By the way the process involved in one of the threads is very long query to a dBase who get many rows, and I only need suspend it in a certain zone of code where the collision occurs (when processing each row) and I can't wait the entire thread to finish join().
这样的区域称为临界区。使用临界区的最简单方法是通过互斥 锁定。
建议的互斥锁解决方案确实是可行的方法,除非您可以证明这是一个热点并且锁争用是一个性能问题。 仅使用原子和内在函数的无锁编程非常复杂,在此级别不推荐。
这是一个简单的示例,展示了如何执行此操作(在 http://liveworkspace.org/code/6af945eda5132a5221db823fa6bde49a 上直播):
#include <iostream>
#include <thread>
#include <mutex>
struct A
{
std::mutex mux;
int x;
A() : x(0) {}
};
void threadf(A* data)
{
for(int i=0; i<10; ++i)
{
std::lock_guard<std::mutex> lock(data->mux);
data->x++;
}
}
int main(int argc, const char *argv[])
{
A instance;
auto t1 = std::thread(threadf, &instance);
auto t2 = std::thread(threadf, &instance);
t1.join();
t2.join();
std::cout << instance.x << std::endl;
return 0;
}
关于c++ - 是否有可能在 C++ 中使用 std::atomic_flag 获得线程锁定机制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12826168/