c ++ 11共享对象存储/加载同步

时间:2015-01-16 07:21:26

标签: multithreading c++11 concurrency atomic

我有一个类型的共享对象:

struct A {
  int x;
  int y;
  int z;
};

A obj;

有2个线程并行运行。

线程#1修改对象的成员:

// .. some code before
obj.x = 42;
obj.y = 42;
obj.z = 42;
// .. now thread #2 can read obj

线程#2读取对象的成员:

// .. some code before
int x = obj.x;
int y = obj.y;
int z = obj.z;
// .. some code after

如果线程#2仅在线程#1修改它们后才能最有效地同步线程#2读取对象的成员?

2 个答案:

答案 0 :(得分:0)

在这里使用std :: atomic。

boost::atomic<int> x { INT_MAX };

// thread1:
while (x.load(memory_order_acquire) == INT_MAX);

// thread2:
x.store(42,memory_order_release);

编辑添加可运行的示例

的main.cpp

#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>

struct Foo {
    Foo(): x_(0) {}
    std::atomic<int> x_;
};

using namespace std;

int main() {
    Foo foo;
    thread th1(
        [&]() {
            cout << "thread1 Waiting for thread2 setting value for x" << endl;
            while (foo.x_.load(memory_order_acquire) == 0);
            int current = foo.x_.load(memory_order_acquire);
            cout << "thread 1 print current value of x is " << current << endl;
        });
    thread th2(
        [&]() {
            std::chrono::milliseconds dura( 2000 );
            std::this_thread::sleep_for( dura );
            cout << "thread2 set up value for x" << endl;
            foo.x_.store(42,memory_order_release);
        });
    th1.join();
    th2.join();
    return 0;
}

的CMakeLists.txt

cmake_minimum_required(VERSION 2.8.4)
project(atomicExample)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++11")

set(SOURCE_FILES main.cpp)
add_executable(atomicExample ${SOURCE_FILES})

答案 1 :(得分:0)

您可以使用std::mutex来同步代码的关键部分。 std::lock_guard锁定互斥锁,并在lock_guard超出范围时释放它。我还添加了一个条件变量,以确保thread2()在继续之前等待thread1()完成为obj分配值。

示例:

#include <mutex>
#include <condition_variable>

struct A {
    int x;
    int y;
    int z;
};

A obj;

std::mutex m;
std::condition_variable cv;
bool thread1Done = false;

void thread1()
{
    std::lock_guard<std::mutex> lock( m );
    obj.x = 42;
    obj.y = 42;
    obj.z = 42;
    thread1Done = true;
    cv.notifyAll();
}

void thread2()
{
    std::unique_lock<std::mutex> lock( m );
    while ( !thread1Done ) {
        cv.wait( lock );
    }

    int x = obj.x;
    int y = obj.y;
    int z = obj.z;
}