C++ 可以在C++;使用std::atomic_标志?

C++ 可以在C++;使用std::atomic_标志?,c++,boost,c++11,boost-thread,atomicity,C++,Boost,C++11,Boost Thread,Atomicity,使用MS Visual C++2012 类具有类型为std::atomic_flag class A { public: ... std::atomic_flag lockFlag; A () { std::atomic_flag_clear (&lockFlag); } }; 有一个类型为A的对象 A object; 谁可以通过两个(Boost)线程访问 如果另一个线程正在访问该对象,则可以等待该线程 问题是:是否有可能用原子标志对象构建这样的机制

使用MS Visual C++2012

类具有类型为
std::atomic_flag

class A {
    public:
    ...
    std::atomic_flag lockFlag;
    A () { std::atomic_flag_clear (&lockFlag); } 
};
有一个类型为A的对象

A object;
谁可以通过两个(Boost)线程访问

如果另一个线程正在访问该对象,则可以等待该线程

问题是:是否有可能用
原子标志
对象构建这样的机制?现在还不是说,我想要一些轻量级的boost::mutex

顺便说一句,其中一个线程所涉及的进程对于获得许多行的数据库来说是一个非常长的查询,我只需要在发生冲突的特定代码区域(处理每一行时)挂起它,我不能等待整个线程完成
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  */
}
但是没有成功,因为第二个线程挂起。事实上,我并不完全理解
原子标志测试和显式设置功能所涉及的机制。如果这样的函数立即返回,或者可以延迟,直到标志可以锁定

对于我来说,如何获得一个带有这样一个函数的锁机制也是一个迷,这个函数总是设置值,然后返回以前的值。没有仅读取实际设置的选项

欢迎提出任何建议

顺便说一句,其中一个线程所涉及的进程对于获得许多行的数据库来说是一个非常长的查询,我只需要在发生冲突的特定代码区域(处理每一行时)挂起它,我不能等待整个线程完成join()

这种区域称为临界截面。处理关键部分的最简单方法是通过互斥锁定

建议的互斥解决方案确实是一条可行之路,除非您能够证明这是一个热点,并且锁争用是一个性能问题。仅使用原子和内部函数的无锁编程非常复杂,在这个级别上不推荐使用

下面是一个简单的示例,展示了如何做到这一点(直播):

#包括
#包括
#包括
结构A
{
std::互斥多路复用器;
int x;
A():x(0){}
};
无效线程F(A*数据)
{
对于(int i=0;imux);
数据->x++;
}
}
int main(int argc,const char*argv[]
{
实例;
auto t1=std::thread(threadf,&instance);
auto t2=std::thread(threadf,&instance);
t1.join();
t2.连接();

std::cout看起来您正在尝试编写一个自旋锁。是的,您可以使用
std::atomic_flag
来实现这一点,但是您最好使用
std::mutex
。除非您真的知道自己在做什么,否则不要使用原子。

要真正回答问题:是的,您可以使用std::atomic_flag来创建线程锁这被称为旋转锁

#include <atomic>

class atomic_lock
{
    public:
        atomic_lock()
            : lock_( ATOMIC_FLAG_INIT )
        {}

        void lock()
        {
            while ( lock_.test_and_set() ) { } // Spin until the lock is acquired.
        }

        void unlock()
        {
            lock_.clear();
        }

    private:
        std::atomic_flag lock_;
};
#包括
类原子锁
{
公众:
原子锁
:lock(原子标志)
{}
无效锁()
{
while(lock.test_和_set()){}//旋转直到获得锁。
}
无效解锁()
{
lock_.clear();
}
私人:
std::原子标志锁;
};

您在寻找无锁算法吗?实际上,您应该只使用互斥来保护您希望同步访问的内容。互斥就是为了保护这些内容。另外,如果您确实希望多个线程同时访问,请使用一个信号量。@Tony我需要进一步了解信号量,但互斥体是否需要成为对象的成员?你能在每个线程中发布一个互斥的简短快照吗?
一个object();
是一个函数声明。gmannicking好的。好的。更正。有一个defaul构造函数。其他一些想法?你是对的。如果我不是因为我对英语的理解太差,你真正想要的是一个自旋锁。我已经阅读了你的书的第5章“C++并发正在运行"我必须承认我并不完全理解它。我觉得一开始我缺少一些东西。无论如何,我计划做一些测试;仔细阅读,作为最后的资源,遵循建议并使用互斥。Glub。请原谅,我之前评论中的问号。我写这篇文章是为了记住你的名字和a之间的一致性这本书的作者。后来我看到了你的个人资料。谢谢你的建议和关于关键部分的指示。我会仔细研究这个例子,当我有答案或任何其他问题时,回到这里。
#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;
}
#include <atomic>

class atomic_lock
{
    public:
        atomic_lock()
            : lock_( ATOMIC_FLAG_INIT )
        {}

        void lock()
        {
            while ( lock_.test_and_set() ) { } // Spin until the lock is acquired.
        }

        void unlock()
        {
            lock_.clear();
        }

    private:
        std::atomic_flag lock_;
};