标签: data-race

在并发编程的上下文中,"数据竞争"和"竞争条件"实际上是相同的

我经常发现这些术语在并发编程的上下文中使用.它们是相同的还是不同的?

language-agnostic concurrency multithreading data-race

82
推荐指数
5
解决办法
2万
查看次数

多线程程序停留在优化模式下,但在-O0下正常运行

我编写了一个简单的多线程程序,如下所示:

static bool finished = false;

int func()
{
    size_t i = 0;
    while (!finished)
        ++i;
    return i;
}

int main()
{
    auto result=std::async(std::launch::async, func);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    finished=true;
    std::cout<<"result ="<<result.get();
    std::cout<<"\nmain thread id="<<std::this_thread::get_id()<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

它通常表现在调试模式下在Visual Studio中-O0GC c和后打印出的结果1秒钟。但是它卡住了,在“ 释放”模式或中不打印任何内容-O1 -O2 -O3

c++ multithreading thread-safety data-race

67
推荐指数
3
解决办法
5653
查看次数

IBM 示例代码,不可重入函数在我的系统中不起作用

我正在学习编程的重入性。在IBM 的这个站点上(非常好)。我已经建立了一个代码,复制在下面。这是第一个在网站上滚动的代码。

该代码尝试通过打印在“危险上下文”中不断变化的两个值来显示涉及在文本程序的非线性开发(异步性)中共享访问变量的问题。

#include <signal.h>
#include <stdio.h>

struct two_int { int a, b; } data;

void signal_handler(int signum){
   printf ("%d, %d\n", data.a, data.b);
   alarm (1);
}

int main (void){
   static struct two_int zeros = { 0, 0 }, ones = { 1, 1 };

   signal (SIGALRM, signal_handler); 
   data = zeros;
   alarm (1);
   while (1){
       data = zeros;
       data = ones;
   }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试运行代码时出现问题(或者更好,没有出现)。我在默认配置中使用 gcc 版本 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)。不会发生被误导的输出。获得“错误”对值的频率为 0!

到底发生了什么?为什么使用静态全局变量重入没有问题?

c gcc signals x86-64 data-race

11
推荐指数
2
解决办法
169
查看次数

TSan 在 Boost 无锁队列中报告数据竞争

我正在使用线程清理程序运行boost 无锁队列文档中给出的 MPMC 示例,令我惊讶的是,这个基本示例包含按照 TSan 的数据竞争。知道可能出了什么问题吗?

OS: Red Hat Enterprise Linux Server release 7.7 / Ubuntu 18.04.4
Compiler: g++ (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2) / g++ (Ubuntu 11.1.0-1ubuntu-18.04.1) 11.1.0
CPU Architecture: x86_64
Boost Version: 1.79
Run Code Online (Sandbox Code Playgroud)

TSan 的输出如下:

@vishal: g++ testQ.cpp -lboost_thread -L /usr/local/lib/ -pthread -fsanitize=thread -ggdb3 -fPIE -pie 

@vishal: TSAN_OPTIONS="history_size=7" ./a.out 

boost::lockfree::queue is lockfree
==================
WARNING: ThreadSanitizer: data race (pid=22019)
  Atomic write of size 8 at 0x7b1000001c00 by thread T1:
    #0 __tsan_atomic64_store <null> (libtsan.so.0+0x800ca)
    #1 std::atomic<boost::lockfree::detail::tagged_ptr<boost::lockfree::queue<int>::node> >::store(boost::lockfree::detail::tagged_ptr<boost::lockfree::queue<int>::node>, …
Run Code Online (Sandbox Code Playgroud)

c++ boost thread-sanitizer data-race

10
推荐指数
0
解决办法
337
查看次数

是否允许此编译器转换?

考虑这个代码,where xy是整数:

if (x)
    y = 42;
Run Code Online (Sandbox Code Playgroud)

是否允许以下​​编译器转换?

int tmp = y;
y = 42;

if (!x)
    y = tmp;
Run Code Online (Sandbox Code Playgroud)

背景:

这是来自Bjarne Stroustrup的FAQ:

// start with x==0 and y==0

if (x) y = 1;   // Thread 1 

if (y) x = 1;   // Thread 2
Run Code Online (Sandbox Code Playgroud)

常见问题解答说这是数据竞争免费; 使用xy0都不应该写入任何变量.
但如果允许转换怎么办?

c++ multithreading c++11 data-race

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

无法理解 go test -race : RACE: DATA WARNING 堆栈跟踪

我在测试我的项目时遇到了数据竞争警告,想知道是否有人愿意帮助我解决这个问题。我过去从未尝试过测试 go 例程,并且发现很难理解数据竞争。

我在描述中提供了未解决问题的链接,并在问题描述中提供了跟踪。

我真的很感激一些帮助,只是从学习调试类似问题和将来为 go 例程编写更好的测试方面来看。

https://github.com/nitishm/vegeta-server/issues/52

下面还提供了跟踪片段

=== RUN   Test_dispatcher_Cancel_Error_completed
INFO[0000] creating new dispatcher                       component=dispatcher
INFO[0000] starting dispatcher                           component=dispatcher
INFO[0000] dispatching new attack                        ID=d63a79ac-6f51-486e-845d-077c8c76168a Status=scheduled component=dispatcher
==================
WARNING: DATA RACE
Read at 0x00c0000f8d68 by goroutine 8:
  vegeta-server/internal/dispatcher.(*task).Complete()
      /Users/nitishm/vegeta-server/internal/dispatcher/task.go:116 +0x61
  vegeta-server/internal/dispatcher.run()
      /Users/nitishm/vegeta-server/internal/dispatcher/task.go:213 +0x17a

Previous write at 0x00c0000f8d68 by goroutine 7:
  vegeta-server/internal/dispatcher.(*task).Run()
      /Users/nitishm/vegeta-server/internal/dispatcher/task.go:107 +0x12a
  vegeta-server/internal/dispatcher.(*dispatcher).Run()
      /Users/nitishm/vegeta-server/internal/dispatcher/dispatcher.go:109 +0xb5f

Goroutine 8 (running) created at:
  vegeta-server/internal/dispatcher.(*task).Run()
      /Users/nitishm/vegeta-server/internal/dispatcher/task.go:105 +0x11c
  vegeta-server/internal/dispatcher.(*dispatcher).Run()
      /Users/nitishm/vegeta-server/internal/dispatcher/dispatcher.go:109 +0xb5f

Goroutine 7 (running) created at:
  vegeta-server/internal/dispatcher.Test_dispatcher_Cancel_Error_completed()
      /Users/nitishm/vegeta-server/internal/dispatcher/dispatcher_test.go:249 +0x545
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:827 +0x162
================== …
Run Code Online (Sandbox Code Playgroud)

testing go race-condition goroutine data-race

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

解决 iOS Swift 中的数据竞争

我有 NetworkProvider,它将连续调用 api,并且一旦我收到数据,我将更新用户 ID。同时我将从其他功能访问用户ID。

这是数据竞争条件,有人可以帮助消除该条件。

`

class NetworkProvider  {
   public var userID: String

   func observeStateChange() {

        FIRAuth.auth()?.addStateDidChangeListener({ (auth, authenticatedUser) in
          if let user = authenticatedUser {
              userID = user.uid
          }
       }
    }

   func currentUserID() -> String {
        return self.userID
  }
}`
Run Code Online (Sandbox Code Playgroud)

grand-central-dispatch swift data-race

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

多个线程可以安全地同时将相同的值写入相同的变量吗?

多个线程可以安全地同时将相同的值写入相同的变量吗?

对于一个特定的例子——下面的代码是否由 C++ 标准保证编译,在没有未定义行为的情况下运行并在每个符合标准的系统上打印“true”?

#include <cstdio>
#include <thread>

int main()
{
    bool x = false;
    std::thread one{[&]{ x = true; }};
    std::thread two{[&]{ x = true; }};
    one.join();
    two.join();
    std::printf(x ? "true" : "false");
}
Run Code Online (Sandbox Code Playgroud)

这是一个理论问题;我想知道它是否总是有效,而不是在实践中是否有效(或者编写这样的代码是否是个好主意:))。如果有人能指出标准的相关部分,我将不胜感激。根据我的经验,它在实践中总是有效,但不知道它是否保证有效,我总是使用它std::atomic- 我想知道这对于这种特定情况是否绝对必要。

c++ multithreading thread-safety data-race

5
推荐指数
2
解决办法
1150
查看次数

将相同的值重新写入内存位置是否算作修改内存?(在多线程的情况下)

(假设:int x{ 6 }并且2个评价x = 6同时写入)

--

CPP 参考资料中提到内存模型:线程和数据竞争

一个表达式的计算写入一个内存位置另一个计算读取修改同一内存位置时,这些表达式被称为冲突。具有两个相互冲突的评估的程序会发生数据竞争,除非:

  • 两个评估在同一线程或同一信号处理程序中执行,或者

  • 两个相互冲突的求值都是原子操作(参见 std::atomic),或者

  • 一个相互冲突的评估发生在另一个评估之前(请参阅 std::memory_order)。

如果发生数据竞争,则程序的行为是不确定的。

参考文献说:“另一评价修改;它没有说“另一篇评论写道

--

C++ 标准关于6.9.2.2 数据竞争的规定:

  1. 如果两个表达式求值之一修改内存位置 ([intro.memory]),而另一个表达式求值读取修改同一内存位置,则两个表达式求值会发生冲突。

--

将相同的值重新写入内存位置是否算作修改内存?

c++ multithreading memory-model c++11 data-race

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

如果两个不同步的线程将计数器递增 X 次,总结果会小于 X 吗?

我在紧密循环中有两个不同步的线程,将全局变量递增 X 次 (x=100000)。

全局的正确最终值应该是 2*X,但由于它们不同步,所以它会更少,根据经验,它通常只是略高于 X

然而,在所有测试运行中, global 的值从未低于 X 。

最终结果有可能小于x(小于100000)吗?

public class TestClass {
    static int global;
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread( () -> {  for(int i=0; i < 100000; ++i) {     TestClass.global++;  }  });
        Thread t2 = new Thread( () -> { for(int i=0; i < 100000; ++i) {     TestClass.global++;  }  });
        t.start(); t2.start();
        t.join(); t2.join();
        System.out.println("global = " + global);
    }
}
Run Code Online (Sandbox Code Playgroud)

java multithreading synchronization race-condition data-race

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