小编use*_*869的帖子

在屏障实现中将代码从顺序一致性更改为不太严格的排序

我在《C++ Concurrency in Action》一书中遇到了这段代码,用于简单实现屏障(对于不能std::experimental::barrier在 C++17 或std::barrierC++20 中使用的代码)。

[编辑]屏障是一种同步机制,其中一组线程(线程数传递给屏障的构造函数)可以到达并等待(通过调用 wait 方法)或到达并丢弃(通过调用 did_waiting) 。如果组中的所有线程都到达屏障,则屏障将被重置,并且线程可以继续执行下一组操作。如果组中的某些线程脱落,则组中的线程数量相应减少,以进行下一轮与屏障的同步。[编辑结束]

以下是为简单实现屏障而提供的代码。

struct barrier
{
   std::atomic<unsigned> count;
   std::atomic<unsigned> spaces;
   std::atomic<unsigned> generation;
   barrier(unsigned count_):count(count_),spaces(count_),generation(0)
   {}
   void wait(){
      unsigned const gen=generation.load();
      if(!--spaces){
         spaces=count.load();
         ++generation;
      }else{
         while(generation.load()==gen){
            std::this_thread::yield();
         }
      }
   }
   void done_waiting(){
      --count;
      if(!--spaces){
         spaces=count.load();
         ++generation;
      }
   }
};
Run Code Online (Sandbox Code Playgroud)

作者 Anthony Williams 提到,他选择顺序一致性排序是为了更容易推理代码,并表示可以使用宽松的排序来提高代码效率。这就是我更改代码以采用宽松排序的方法。请帮助我理解我的代码是否正确。

struct barrier
{
   std::atomic<unsigned> count;
   std::atomic<unsigned> spaces;
   std::atomic<unsigned> generation;
   barrier(unsigned count_):count(count_),spaces(count_),generation(0)
   {}
   void wait(){
      unsigned const gen=generation.load(std::memory_order_acquire);
      if(1 == spaces.fetch_sub(1, std::memory_order_relaxed)){
         spaces=count.load(std::memory_order_relaxed);
         generation.fetch_add(1, std::memory_order_release); …
Run Code Online (Sandbox Code Playgroud)

c++ atomic memory-barriers barrier stdatomic

7
推荐指数
1
解决办法
194
查看次数

了解共享引用对嵌套数据结构的影响

所有权树

\n

所有权树

\n

你好,

\n

我试图理解 Rust 中的所有权概念,并在“Programming Rust”一书中看到了这张图片(附在这篇文章中)。

\n

我特别关心“借用共享参考”部分。作者在书中说道

\n
\n

共享引用借用的值是只读的。在共享引用的整个生命周期中,其引用对象以及从该引用对象可访问的任何内容都不能被任何内容更改。不存在对该结构中任何内容的实时可变引用,其所有者是只读的,等等。它\xe2\x80\x99s真的冻结了

\n
\n

在图中,他继续强调沿着所有权树的路径,一旦对所有权树的特定部分采用共享引用,该路径就变得不可变。但令我困惑的是,作者还提到所有权树的某些其他部分不是只读的。

\n

所以我尝试用这段代码进行测试:

\n
 fn main(){                                                                                                    \n    let mut v = Vec::new();                                                                                   \n    v.push(Vec::new());                                                                                       \n    v[0].push(vec!["alpha".to_string()]);                                                                                    \n    v[0].push(vec!["beta".to_string(), "gamma".to_string()]);                                                                                                                                                                                                                                                \n    let r2 = &(v[0][1]); //Taking a shared reference here                                                                                    \n    v[0][0].push("pi".to_string());                                                                           \n    println!("{:?}", r2)                                                                                      \n}\n
Run Code Online (Sandbox Code Playgroud)\n

我知道它v[0][0]不能是可变的,因为v它本身是一个不可变的共享引用(作为对 的共享引用的结果v[0][1])并且 Rust 编译器有用地指出了这一点。我的问题是,当作者将所有权树上的某些部分标记为“非只读”时,我们如何访问这些部分来更改它们?

\n

如果我的代码片段不是作者想要传达的内容的正确示例,请帮助我提供一个示例来演示作者在这里试图暗示的内容。谢谢。

\n

rust

5
推荐指数
1
解决办法
592
查看次数

尝试使用模块时标准库内容的多重定义错误

我有两个文件 Interface.cppm(主模块接口单元)和 main.cpp。我没有该模块的任何其他模块单元。

在Interface.cppm中,我有以下内容

module;

#include <cstdint>

export module Interface; 

import <algorithm>;
import <iostream>;
import <memory>;
import <sstream>;
import <string>;
import <tuple>;
import <type_traits>;
import <vector>;

//Code that this interface exports and
//implementation details.
Run Code Online (Sandbox Code Playgroud)

我是 main.cpp,我有以下代码:

import Interface;
import <iostream>;
import <memory>;
import <string>;

int main(){
    //Using the contents of Interface module
}
Run Code Online (Sandbox Code Playgroud)

我预编译了标头单元并将它们放在名为 header-units 的文件夹中。然后我使用以下命令编译我的代码:

clang++ -std=c++20 Interface.cppm -fmodule-file=./header-units/algorithm.pcm -fmodule-file=./header-units/iostream.pcm --precompile -fmodule-file=./header-units/memory.pcm -fmodule-file=./header-units/sstream.pcm -fmodule-file=./header-units/string.pcm -fmodule-file=./header-units/tuple.pcm -fmodule-file=./header-units/type_traits.pcm -fmodule-file=./header-units/vector.pcm -fmodule-file=./header-units/unordered_map.pcm -o Interface.pcm    //This works fine

clang++ -std=c++20 main.cpp -fmodule-file=Interface.pcm -fmodule-file=./header-units/iostream.pcm -fmodule-file=./header-units/string.pcm …
Run Code Online (Sandbox Code Playgroud)

c++ c++20 c++-modules

3
推荐指数
1
解决办法
951
查看次数

标签 统计

c++ ×2

atomic ×1

barrier ×1

c++-modules ×1

c++20 ×1

memory-barriers ×1

rust ×1

stdatomic ×1