是否可以使用std :: atomic_flag在C++中获得线程锁定机制?

Old*_*bie 2 c++ boost boost-thread atomicity c++11

使用MS Visual C++ 2012

类具有类型的成员 std::atomic_flag

class A {
    public:
    ...
    std::atomic_flag lockFlag;
    A () { std::atomic_flag_clear (&lockFlag); } 
};
Run Code Online (Sandbox Code Playgroud)

有一个类型A的对象

A object;
Run Code Online (Sandbox Code Playgroud)

谁可以被两个(Boost)线程访问

void thr1(A* objPtr) { ... }
void thr2(A* objPtr) { ... }
Run Code Online (Sandbox Code Playgroud)

如果另一个线程正在访问该对象,则该想法是等待该线程.

问题是:是否有可能用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  */
}
Run Code Online (Sandbox Code Playgroud)

但没有成功,因为第二个线程挂起.实际上,我并不完全理解该atomic_flag_test_and_set_explicit函数所涉及的机制.如果这样的函数不能立即返回,或者可以延迟直到可以锁定标志.

对我来说,如何获得一个具有这样一个函数的锁定机制并始终设置该值并返回之前的值也是一种谜.没有选项只能读取实际设置.

欢迎任何建议.

seh*_*ehe 8

顺便说一下,其中一个线程涉及的进程是一个非常长的查询到获得很多行的dBase,我只需要在发生冲突的某个代码区域中挂起它(当处理每一行时)我不能等待整个线程完成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;
}
Run Code Online (Sandbox Code Playgroud)