标签: thread-safety

跨线程共享具有特征对象作为属性的结构

我有下面的代码。随着注释掉的部分,它的工作。当我取消注释这些部分时,它不再编译。

如何调整注释部分以使其工作,即,我想让线程同时访问表达式树。

当我尝试它时,编译器从关于线程安全性的错误开始。

我读过 Rust 的书,知道 C/C++,但还没有完全理解 Rust 类型系统和语义。

use std::thread;
use std::sync::Arc;

pub trait Expr {
    fn run(&self) -> i32;
}

pub struct ConstantExpr {
    n: i32,
}

impl ConstantExpr {
    pub fn new(n: i32) -> Self {
        Self { n }
    }
}

impl Expr for ConstantExpr {
    fn run(&self) -> i32 {
        self.n
    }
}

pub struct AddExpr {
    expr1: Box<Expr>,
    expr2: Box<Expr>,
}

impl AddExpr {
    pub fn new(expr1: Box<Expr>, expr2: Box<Expr>) -> Self {
        Self …
Run Code Online (Sandbox Code Playgroud)

thread-safety lifetime rust

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

Hazelcast IMap put 方法获取存储桶或分区或键的锁?

Hazelcast IMap put 方法获取存储桶或分区或键的锁? java.util.concurrent.ConcurrentHashMapput 方法获取存储桶上的锁并写入 Map。
而在 Hazelcast IMap 中,这是一种分布式地图实现java.util.concurrent.ConcurrentHashMap,当以下代码由一个 Hazelcast 节点执行时。
imap.put(key, value);
它是否获得了对存储桶、分区或密钥的锁定?请说清楚?我在 hazelcast 文档中的任何地方都没有看到这个问题的答案。

java multithreading synchronization thread-safety hazelcast

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

vert.x 中的多实例垂直是线程安全的

我知道在 vert.x 中,每次我们不需要在处理程序中编写线程安全时,默认的 Verticle 都会在同一个事件循环中运行。

例如,如果我有一个运行 HttpServer 的 Verticle -

public class HttpServerVerticle extends AbstractVerticle {
@Override
public void start() throws Exception {
    vertx.createHttpServer().requestHandler(req -> {
        req.response().putHeader("content-type", "text/html").end(" 
    <html><body><h1>Hello from vert.x!</h1></body></html>");
    }).listen(8080);
}
Run Code Online (Sandbox Code Playgroud)

}

保证在任何时候,我的请求处理程序都会在 2 个事件循环中被调用两次(针对 2 个不同的请求)。因此,我不必在我的请求处理程序中处理线程安全。

现在,如果我正在运行 HttpServer verticle 的多个实例 -

DeploymentOptions deploymentOptions = new 
        DeploymentOptions().setWorker(false).setInstances(10);

vertx.deployVerticle("com.....HttpServerVerticle", deploymentOptions);
Run Code Online (Sandbox Code Playgroud)

我需要注意线程安全吗?多个请求处理程序(最大 = 10)有可能并行运行吗?

thread-safety vert.x

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

ConcurrentBag 字符串并在 Parallel.ForEach 中使用 .Contains

我使用 ConcurrentBag 来包含字符串列表。有时它会包含一个副本。

但是我在添加新条目之前检查了它的内容,所以它不应该有重复。

ConcurrentDictionary<string, string> SystemFiles = PopulateSystemFiles();
ConcurrentBag<string> SystemNames = new ConcurrentBag<string>();

Parallel.ForEach(SystemFiles, file =>
{
    string name = GetSystemName(file.Value);

    if (!SystemNames.Contains(name))
    {
        SystemNames.Add(name);
    }
});
Run Code Online (Sandbox Code Playgroud)

我的假设是 .Contains 方法不是线程安全的。我对么?

c# parallel-processing concurrency multithreading thread-safety

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

将标准 Golang Map 转换为 Sync.Map 以避免竞争条件

我有以下代码行:

var a_map = make(map[string] []int)
Run Code Online (Sandbox Code Playgroud)

我使用 a_map 变量的部分代码偶尔会引发以下错误:

fatal error: concurrent map read and map write
Run Code Online (Sandbox Code Playgroud)

为了创建一个更健壮的解决方案,一个没有此类错误的解决方案,我想使用一个 sync.Map 而不是通用映射。对此堆栈溢出问题提供的唯一答案启发了我这样做。但是,我不清楚这样做的正确语法。

对于我的第一次尝试,我使用了以下代码行:

var a_map = make(sync.Map[string] []int)
Run Code Online (Sandbox Code Playgroud)

这导致了以下错误:

...syntax error: unexpected ], expecting expression
Run Code Online (Sandbox Code Playgroud)

然后我尝试:

 sync_map := new(sync.Map)
 var a_map = make(sync_map[string] []int)
Run Code Online (Sandbox Code Playgroud)

这导致了同样的错误:

...syntax error: unexpected ], expecting expression
Run Code Online (Sandbox Code Playgroud)

mutex thread-safety go race-condition goroutine

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

为什么 a+=1 是 ruby​​ 中的线程安全操作?

代码片段:

a = 0
Array.new(50){
  Thread.new {
    500_000.times { a += 1 }
  }
}.each(&:join)
p "a: #{a}"
Run Code Online (Sandbox Code Playgroud)

结果:a = 25_000_000

据我了解,(MRI) Ruby 使用 GIL,所以只有一个 ruby​​ 线程可以获得 CPU,但是当发生线程切换时,会存储一些 ruby​​ 线程的数据,以便稍后恢复线程。所以,理论上,a += 1可能不是线程安全的。

但上面的结果证明我错了。Ruby 是否具有a+=1原子性?如果为真,哪些操作可以被认为是线程安全的?

ruby multithreading thread-safety

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

Java 发生在关系之前?

考虑以下代码。

public class Test {
    private boolean running = false;

    public void run() {
        running = true;
    }

    public void test() {
        boolean running1 = running;
        boolean running2 = running;
        System.out.println("running1: " + running1);
        System.out.println("running2: " + running2);
    }
}
Run Code Online (Sandbox Code Playgroud)

线程 A 调用run(),然后另一个线程 B 调用test()并且不应该有任何发生之前的关系。我知道不能保证线程 B 看到线程 A 所做的更改。但是这个程序的输出有没有可能是:

running1: true
running2: false
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading thread-safety happens-before

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

如何将元素添加到数组的线程安全函数?

我编写了以下函数,它接受一个对象 ( element),在现有向量 ( elements) 中为它腾出空间,并通过添加新对象来更新向量:

void addElement(const ElementType& element) {
    if (numElements == elements.size()) {
        elements.resize(boost::extents[numElements+1]);
    }

    elements[numElements] = element;

    numElements++;
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能使它对 MPI 线程安全?据我了解,每个线程都知道的大小elements是多少,因此我不明白为什么这个函数不是线程安全的。numElements在此函数外初始化为零,并且是elements向量的大小。

编辑:我使用上面写的函数和 mtx 锁定和解锁如下,但最终elements向量仍然只包含来自第一级的数据。

    #pragma omp parallel for collapse(3) schedule(static)
    for (long n0 = mgr->startN0; n0 < mgr->startN0 + mgr->localN0; n0++) {
      for (int n1 = 0; n1 < ?; n1++) {
        for (int n2 = 0; n2 < ?; n2++) {
          ElementType element;
          std::mutex …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading thread-safety c++11 stdthread

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

线程填充集合和 Java 内存模型

我注意到,如果我让一个线程填充一个集合,在 之后的线程末尾join,我会看到该集合按预期填充。

关于 Java 内存模型,这是否总是保证发生?

如果线程将列表中对象的引用存储在 cpu 缓存中怎么办?
在这种情况下,加入后加入线程必须保证看到变化?

final ArrayList<Person> persons = new ArrayList();
Thread myThread = new MyThread(persons);
myThread.start();
myThread.join();

// persons ?
Run Code Online (Sandbox Code Playgroud)

线

public class MyThread extends Thread {
    
    ArrayList<Person> persons;

    public MyThread(ArrayList<Person> persons){
     this.persons = persons;
    }

    public void run(){
      persons.add(new Person(...))
      // add more
    }
  }
Run Code Online (Sandbox Code Playgroud)

java collections multithreading thread-safety

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

std::atomic&lt;T&gt;::operator= 如何为不可变类型实现?

我了解到线程之间通信的一种方法是共享一些原子数据结构。例如:

struct Point {
    int const x, y;
};

std::atomic<Point> some_point_in_shared_memory{Point{0, 0}};
Run Code Online (Sandbox Code Playgroud)

尽管Point::operator=(Point const &)被删除,但调用赋值运算符似乎没有问题std::atomic<Point>,如下所示:

some_point_in_shared_memory = Point{1, 2};
Run Code Online (Sandbox Code Playgroud)

如何实施此操作?

我可能会想到的一种解决方案是使用placement new在旧对象之上构造一个新对象,但显然它不是异常安全的。还是因为Point可以简单地复制而没关系?

c++ thread-safety exception-safety stdatomic

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