如何让两个线程通过指针交换数据?

时间:2013-05-17 16:16:56

标签: c++ multithreading function pointers atomic

我想要一个异步线程来编辑一个对象。因此,我存储了一个指向该对象的指针。

Data *pointer;

还有一个类型为std::atomic<bool>的标志,以便知道辅助线程是否正在修改指针指向的对象。当标志成立时,主线程不会影响指针及其底层对象。

std::atomic<bool> modifying;

void Thread()
{
    // wait for jobs
    for(;;)
    {
        // the flag is set to true my the main thread
        // to let this thread start processing
        if(modifying)
        {
            // modify the object the pointer points to,
            // pass the pointer to a function to do so,
            // and so on...

            // the flag to false to tell the main thread
            // that it can read the result from the pointer
            // and prepare it for the next job
            modifying = false;
        }
    }
}
  • 如何确保线程安全?

我无法通过std::atomic包装指针,因为从辅助线程我需要将指针传递给期望非原子Data*类型作为参数的函数。

  • 指针甚至需要特别声明为原子?在编写单个寄存器时,我认为处理器不会改变线程。或者我是否必须使其成为原子以防止不必要的编译器优化?
  • 如果指针是原子的,底层对象也是如此吗?换句话说,我可以使用从pointer.load()获得的指针修改对象吗?

感谢您的澄清。

1 个答案:

答案 0 :(得分:1)

听起来你想要的是拥有编辑对象的权限互斥。这正是制作互斥锁的原因。

通常,假设您有线程A和B,两者都想要更新相同的指针。例如,当A想要进行编辑时,它会尝试锁定()互斥锁。如果互斥锁尚未被B锁定,则会成功,并且A可以执行其操作。如果互斥锁 已被B锁定,则A将阻止(即停止执行),直到B释放其对互斥锁的锁定,此时A将继续并且做正常的事情。

对于C ++ 11的互斥体语法的更具体的例子,这个页面做得很好: http://en.cppreference.com/w/cpp/thread/mutex

当然,我建议使用pthreads库来解释互斥体(以及其他线程概念): https://computing.llnl.gov/tutorials/pthreads/#Mutexes

在您的情况下,您的代码可能如下所示:

std::mutex editing;

void Thread()
{
    for(;;)
    {
        editing.lock();

        // Do whatever editing you wanted to do here.

        editing.unlock();
    }
}

值得注意的是std :: mutex类上的try_lock()函数。这与lock()非常相似,除非互斥锁已被锁定,否则它将返回false以指示无法获取锁定,并继续。如果你想让你的线程忘记编辑对象并在另一个线程已经在编辑对象时继续,而不是等待另一个线程再编辑,这将非常有用。