Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何让两个线程通过指针交换数据?_C++_Multithreading_Function_Pointers_Atomic - Fatal编程技术网

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

C++ 如何让两个线程通过指针交换数据?,c++,multithreading,function,pointers,atomic,C++,Multithreading,Function,Pointers,Atomic,我需要一个异步线程来编辑对象。因此,我存储一个指向该对象的指针 Data *pointer; 还有一个类型为std::atomic的标志,用于知道次线程是否正在修改指针指向的对象。虽然该标志为true,但主线程不会影响指针及其底层对象 std::atomic<bool> modifying; void Thread() { // wait for jobs for(;;) { // the flag is set to true my th

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

Data *pointer;
还有一个类型为
std::atomic
的标志,用于知道次线程是否正在修改指针指向的对象。虽然该标志为true,但主线程不会影响指针及其底层对象

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::原子修改;
无效线程()
{
//等待工作
对于(;;)
{
//该标志在主线程中设置为true
//让此线程开始处理
如果(修改)
{
//修改指针指向的对象,
//将指针传递给要执行此操作的函数,
//等等。。。
//将标志设置为false以指示主线程
//它可以从指针读取结果
//为下一项工作做好准备
修改=假;
}
}
}
  • 如何确保线程安全
我无法通过
std::atomic
包装指针,因为我需要从辅助线程将指针传递给一个函数,该函数需要一个非原子
Data*
类型作为参数

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

感谢您的澄清。

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

通常,假设您有线程A和线程B,这两个线程都希望更新同一个指针。例如,当A想要进行编辑时,它会尝试锁定互斥锁()。如果互斥锁还没有被B锁定,这将成功,A可以完成它的任务。如果互斥体已被B锁定,则A将阻塞(即停止执行),直到B释放其对互斥体的锁定,此时A将继续并正常执行其操作

对于C++11互斥体语法的更具体示例,本页做得很好:

当然,我建议使用pthreads库来解释互斥锁(和其他线程概念):

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

std::mutex editing;

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

        // Do whatever editing you wanted to do here.

        editing.unlock();
    }
}

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

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

通常,假设您有线程A和线程B,这两个线程都希望更新同一个指针。例如,当A想要进行编辑时,它会尝试锁定互斥锁()。如果互斥锁还没有被B锁定,这将成功,A可以完成它的任务。如果互斥体已被B锁定,则A将阻塞(即停止执行),直到B释放其对互斥体的锁定,此时A将继续并正常执行其操作

对于C++11互斥体语法的更具体示例,本页做得很好:

当然,我建议使用pthreads库来解释互斥锁(和其他线程概念):

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

std::mutex editing;

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

        // Do whatever editing you wanted to do here.

        editing.unlock();
    }
}

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

我开始写答案,但意识到我并不真正理解您在做什么。什么改变了原子值?什么样的变化?您实际上是在试图保护
数据
还是指向
数据
的指针。这个问题看起来好像你在尝试做一些事情,而不是原子的用途。基本上,我希望两个线程通过指针进行通信。主线程将数据设置为指向一个对象并启动另一个线程。另一个线程更改指针指向的对象。这就是全部。我会使用一个由atomic包装的指针,但是我不能将它传递给我想从另一个线程中调用的函数。我希望现在更清楚。好吧,但我想我会给出一个不是基于原子的答案,因为我不知道原子在这种情况下有什么意义。那太好了。正如我在问题中提到的,我还没有完全理解原子指针。在这种情况下,它们可能不是解决问题的方法。嗯,我正朝着一个互斥的答案前进,但我想我现在不需要提供这个答案。看起来你仍然在
线程中浪费CPU时间。我开始写答案,但意识到我并不真正理解你在做什么。什么改变了原子值?什么样的变化?您实际上是在试图保护
数据
还是指向
数据
的指针。这个问题看起来好像你在尝试做一些事情,而不是原子的用途。基本上,我希望两个线程通过指针进行通信。主线程将数据设置为指向一个对象并启动另一个线程。另一个线程更改