强制同时修改变量 (C++)

     2023-02-22     301

关键词:

【中文标题】强制同时修改变量 (C++)【英文标题】:Enforce concurrent modification of a variable (C++) 【发布时间】:2018-11-21 14:15:45 【问题描述】:

我正在尝试对原子库进行单元测试(我知道原子库不适合进行单元测试,但我仍然想尝试一下)

为此,我想让 X 个并行线程增加一个计数器并计算结果值(应该是 X)。

代码如下。问题是它永远不会中断。 Counter 总是以 2000 结尾(见下文)。我还注意到cout 也作为一个整体打印(而不是混合在一起,我记得在其他多线程couts 中看到的)

我的问题是:为什么这不会中断?或者我怎样才能让它中断?

#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <condition_variable>

std::mutex m;
std::condition_variable cv;
bool start = false;

int Counter = 0;

void Inc() 

    // Wait until test says start
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, [] return start; );

    std::cout << "Incrementing in thread " << std::this_thread::get_id() << std::endl;
    Counter++;


int main()

    std::vector<std::thread> threads;

    for (int i = 0; i < 2000; ++i) 
        threads.push_back(std::thread(Inc));
    

    // signal the threads to start
    
        std::lock_guard<std::mutex> lk(m);
        start = true;
    
    cv.notify_all();

    for (auto& thread : threads) 
        thread.join();
    

    // Now check whether value is right
    std::cout << "Counter: " << Counter << std::endl;

结果看起来像这样(但后来有 2000 行)

Incrementing in thread 130960
Incrementing in thread 130948
Incrementing in thread 130944
Incrementing in thread 130932
Incrementing in thread 130928
Incrementing in thread 130916
Incrementing in thread 130912
Incrementing in thread 130900
Incrementing in thread 130896
Counter: 2000

任何帮助将不胜感激

更新:将线程的 nr 减少到 4,但在 for 循环中增加一百万次(如 @tkausl 所建议),线程 ID 的 cout 似乎是连续的。..

UPDATE2:事实证明,必须解锁锁以防止每个线程的独占访问 (lk.unlock())。 for 循环中的额外yield 增加了竞争条件效果。

【问题讨论】:

线程太多而做的太少。尝试使用两个或四个线程,每个线程在循环中将变量递增一百万次。 您正在尝试制作一个 heisenbug。没有 100% 的方法。 @tkausl Tnx,查看更新 coliru.stacked-crooked.com/a/4f0b8c68851694c6 【参考方案1】:

cv.wait(lk, [] return start; ); 仅返回获得的lk。所以是排他的。你可能想在之后解锁lk

void Inc() 
    // Wait until test says start
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, [] return start; );
    lk.unlock();

    Counter++;

您必须删除std::cout,因为它可能会引入同步。

【讨论】:

couts 似乎混合了一段时间。不过,还没有看到不一致的计数器。 @Ben 在我的电脑(E5-1620)上,它给出了 ~1999,但大部分是 2000。 在 for 循环中添加睡眠(请参阅更新)会有所帮助。现在终于不行了:)

从库 C++ 中设置环境变量

...:所以基本上我试图在我的C++代码中设置一个环境变量来强制线程数为1。我正在使用多个机器学习库,默认情况下使用OpenMP并且可以强制在单线程中运行通过设置以下环境变量模式:OMP_NUM_THREADS=1这是我的问题。我想在我正在构... 查看详情

C++:如何修改类变量?

】C++:如何修改类变量?【英文标题】:C++:howdoesclassvariablegetmodified?【发布时间】:2013-04-1504:48:22【问题描述】:来自关于constfunctions的MSDN页面代码://constant_member_function.cppclassDatepublic:Date(intmn,intdy,intyr);intgetMonth()const;//Aread-onlyf... 查看详情

c++之强制转换

    C语言当中的强制转换基本没有任何的限制,只需要一个括号即可,而在C++中,对强制转换有了一定的限制,这样避免了我们在使用时造成的不明确问题,同时也增加了代码的可读性。一共有四种,分别时static_c... 查看详情

为何在c++中要将一个char型的变量以数的形式输出需要将其强制转换成int型的,而单片机中不用

...在c++中要将一个char型的变量以数的形式输出,需要将其强制转换成int型的,而单片机中不用(即char型的数出来就是一个数)任何变量在内存中的存储都是二进制数。在输出的时候,c++中,cout<<输出一个char型变量默认就是字... 查看详情

访问和修改包含具有不同变量类型的对象的 C++ 向量

】访问和修改包含具有不同变量类型的对象的C++向量【英文标题】:AcessandmodifyaC++vectorcontainingobjectswithdifferentvariabletypes【发布时间】:2020-12-1221:03:24【问题描述】:我刚开始学习C++,我想访问和修改具有不同变量类型的对象向... 查看详情

将变量作为基类对象迭代,同时转换为子类并在 C++ 中使用它们的覆盖方法

】将变量作为基类对象迭代,同时转换为子类并在C++中使用它们的覆盖方法【英文标题】:IteratethroughvariablesasBaseclassobjectswhilecastingtoChildclassesandusetheiroverridenmethodsinC++【发布时间】:2020-12-0722:51:56【问题描述】:我正在尝试做一... 查看详情

强制清理临时变量

】强制清理临时变量【英文标题】:Forcecleanupoftemporaryvariables【发布时间】:2018-03-1016:32:24【问题描述】:(如果这个问题是重复的,请原谅,我是初学者,不知道要搜索什么词才能找到答案!)我正在尝试为C++编写一个带有一... 查看详情

是否可以强制转换 c++ 运算符新输出? [关闭]

】是否可以强制转换c++运算符新输出?[关闭]【英文标题】:Isthatpossibletocastc++operatornewoutput?[closed]【发布时间】:2019-08-2908:37:59【问题描述】:我编写了以下函数,它将打印出环境变量的值,但是当我编译它时,它显示以下错误... 查看详情

如何使用 gmock 模拟修改 C++ 类中的私有变量的成员函数?

】如何使用gmock模拟修改C++类中的私有变量的成员函数?【英文标题】:HowtomockmemberfunctionsthatmodifyprivatevariablesinaC++class,usinggmock?【发布时间】:2019-11-1815:32:07【问题描述】:我正在努力解决使用gmock进行模拟的问题。下面的简化... 查看详情

如何允许多个线程同时修改一个类的变量

】如何允许多个线程同时修改一个类的变量【英文标题】:Howtoallowaclass\'svariablestobemodifiedconcurrentlybymultiplethreads【发布时间】:2020-04-2217:28:55【问题描述】:我有一个类(MyClass),其中包含需要运行的操作队列(self.msg_queue),并且... 查看详情

inta和(int&)a的区别(转)

(1)语言的类型的强制转换不会修改原来的数据,会另外的开辟一个临时的或者程序中指定的空间来存储强制转换后的值。(2)C++引用的实现是在符号表中动了手脚,把自己的变量符号对应的内存地址写成了它所引用的那个变... 查看详情

使用全局变量,当多个线程同时修改静态属性第三季

ThreadLocal介绍  我们知道,变量从作用域范围进行分类,可以分为“全局变量”、“局部变量”两种:  1.全局变量(globalvariable),比如类的静态属性(加static关键字),在类的整个生命周期都有效;  2.局部... 查看详情

使用全局变量,当多个线程同时修改静态属性第二季

ThreadLocal介绍  我们知道,变量从作用域范围进行分类,可以分为“全局变量”、“局部变量”两种:  1.全局变量(globalvariable),比如类的静态属性(加static关键字),在类的整个生命周期都有效;  2.局部... 查看详情

c++核心准则c.7:不要在一条语句内声明类或枚举值的同时又定义该类型的变量

C.7:Dontdefineaclassorenumanddeclareavariableofitstypeinthesamestatement不要在一条语句内声明类或枚举类型的同时又定义该类型的变量Reason(原因)Mixingatypedefinitionandthedefinitionofanotherentityinthesamedeclarationisconfusingandunne 查看详情

我可以像在 c++ 中使用指针一样修改函数中的变量而不在 python 中返回吗

】我可以像在c++中使用指针一样修改函数中的变量而不在python中返回吗【英文标题】:Canimodifyvariableinfunctionwithoutreturninpythonlikeusingpointersinc++【发布时间】:2022-01-1402:33:33【问题描述】:我只是想学习如何在python中编写这个c++代... 查看详情

用 VS 调试 C++。追踪变量变化

...个包含全局变量的大型程序(VS项目)。它从数百个地方修改。实际上它是标准的STL容器(std::vector),问题是我如何追踪这个特定的变量修改?在我的工作中,我使用VS调试器(Prof201715.9.5)【问题讨论】:【参考方案1】: 查看详情

有没有一种可靠的方法可以强制线程在 C++ 中停止? (尤其是分离的)

】有没有一种可靠的方法可以强制线程在C++中停止?(尤其是分离的)【英文标题】:IsthereareliablewaytoforceathreadtostopinC++?(especiallydetachedones)【发布时间】:2016-05-1716:11:37【问题描述】:我最近正在使用C++11中的线程。现在我正在... 查看详情

C++ 强制 mem_fun 选择特定的重载成员函数

】C++强制mem_fun选择特定的重载成员函数【英文标题】:C++forcingmem_funtoselectaspecificoverloadedmemberfunction【发布时间】:2012-03-0515:55:08【问题描述】:我实际上已经想出了如何按照我的问题标题所暗示的方式去做,但不是以一种令人... 查看详情