1

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

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()对象吗?

感谢您的澄清。

4

1 回答 1

1

听起来您想要的是拥有编辑对象的特权是互斥的。这正是互斥锁的用途。

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

有关 C++11 互斥体语法的更具体示例,此页面做得很好: http ://en.cppreference.com/w/cpp/thread/mutex

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

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

std::mutex editing;

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

        // Do whatever editing you wanted to do here.

        editing.unlock();
    }
}

还值得注意的是 std::mutex 类上的 try_lock() 函数。这与 lock() 非常相似,但如果互斥锁已被锁定,则它只会返回 false 以指示无法获取锁,然后继续。如果您希望您的线程忘记编辑对象并在另一个线程已经在编辑对象时继续,而不是等待另一个线程然后进行编辑,这将很有用。

于 2013-05-17T17:03:46.360 回答