gpt4 book ai didi

c++ - 如果在触发 if 语句后触发条件失败,是否存在 IF 语句提前退出的情况?

转载 作者:行者123 更新时间:2023-12-04 11:12:27 25 4
gpt4 key购买 nike

问题:对于包含使触发它的条件无效的代码的条件语句,是否存在条件会在没有中断函数的情况下过早退出的条件?与此类似:

IF(x == 0){x=1;}
背景
我正在使用一个相当大的 c++ 程序,该程序由一个充当包装器的商业程序组成。这个包装器处理 etherCAT 通信和与计算机链路层的接口(interface),我的程序存在于其中。我的程序存在 3 个线程(此商业包装器中存在其他线程,但我对它们的信息有限):
  • MyAppPD:商业函数,从内存中检索 EtherCAT PD 信息并将其传递给全局类。该线程与 EtherCAT 周期同步运行,我几乎无法控制它的内存访问。
  • 转换:该线程从全局类接收数据,对其进行处理,并通过全局类将输出返回给 MyAppPD。该线程与 MyAppPD 同步运行。
  • 计算:该线程与其他线程异步运行,通过全局类接收数据,因为它在转换中可用。它的输出通过相同的全局类返回到 Conversions。
  • 全局类:我一直提到的全局类是一个对象,它通过使用 pthread 互斥锁在两个线程之间来回传递数据。每个数据路径都使用一个锁(转换 -> 计算和计算 -> 转换由两个锁组成),私有(private)类变量用作临时存储,因此在没有互斥锁的情况下,来自一个线程的数据永远不会被另一个线程直接访问先申请。

  • 深度问题:
    最近我为这个全局类添加了一个新级别,以促进轨迹数据从计算到转换的传输。它由以下形式的结构组成:
    struct DCommand {
    struct DOptions {
    bool CSPI = false;
    bool Blend = false;
    bool Cyclic = false;
    bool StopM = false;
    };
    DOptions Opt;
    struct Drive {
    int INC_max;
    bool Init_Accel = false;
    bool Init_MTorq = false;
    std::vector<int32_t> Th = std::vector<int32_t>(200);
    std::vector<uint32_t> ThDot = std::vector<uint32_t>(200);
    std::vector<uint32_t> ThDotDot = std::vector<uint32_t>(200);
    std::vector<uint16_t> MTorq = std::vector<uint16_t>(200);
    };
    Drive D1;
    Drive D2;
    };
    这个结构从计算线程传递到全局类(通过互斥锁),在那里它被复制到一个私有(private)全局结构,这个操作设置一个 bool 值。转换线程在每个周期查询全局类以检查新数据是否可用,如果 bool 值为真,则启动查询。从全局类到Conversions的查询函数如下:
    DCommand PDSync::Sync2Conv(){
    DCommand Out_DCom; //Create temporary struct

    pthread_mutex_lock(&Calc_lock_mutex);

    Out_DCom = DrvCom; //copy intermediate struct

    pthread_mutex_unlock(&Calc_lock_mutex);

    Conv_shouldread = false; //If true, Conv_ReadAvail returns true

    return Out_DCom;
    }
    来自 Conversions 的请求函数如下:
    if(ThreadSync.Conv_ReadAvail()){ 
    ConvDrv = ThreadSync.Sync2Conv();

    TS.SetEE_LoadStruct(ConvDrv); //Copy struct from threadsync to local trajectory
    }
    其中 ThreadSync 是全局类对象。现在,此代码由于某种原因出现故障。我可以将问题追溯到“Sync2Conv”中的“return”语句之前,其中一个简单的 cout 跟踪器可以正常工作,它充当语句“ConvDrv = ThreadSync.Sync2Conv();”不完成。更奇怪的是,在语句“if(ThreadSync.Conv_ReadAvail())”之后的程序就好像遇到了一个简单的中断一样继续执行;在 if 语句中。更奇怪的是,一旦我 CTRL+C 退出程序(在商业包装器上设置关闭并终止 ethercat 连接),语句 Sync2Conv 和 SetEE_LoadStruct 就在关闭之前完成。
    尝试解决问题:
  • 重命名从全局类接收数据的转换线程结构,以防它碰巧与商业包装器中的某些函数具有冲突标识符。
  • 检查互斥锁是否存在死锁情况。不存在。
  • 检查是否只有适当的线程试图通过 pthread_self() 访问 Sync2Conv 函数。在程序的生命周期内,没有其他线程访问该函数。
  • 逐行依次停用该功能,这使我找到了迄今为​​止唯一找到的解决方案:

  • 部分解决方案:
    停用防止重复读取 Sync2Conv 函数的触发器:
    Conv_shouldread = false; //If true, Conv_ReadAvail returns true
    将允许程序正确进行,但随后每个周期都会访问该功能,而不仅仅是在新数据可用时。这有点像当允许 IF 条件语句的变量切换状态时,IF 条件退出(或以某种方式挂起)。任何人都可以提供这方面的建议吗?
    完整解决方案
    竞争条件似乎出现在上面显示的条件 IF 语句的触发条件内。 bool 值 Conv_shouldread 在触发条件中使用以确定何时尝试访问全局中的数据。
    在 bool 访问点周围扩展相同的互斥锁,以便在触发条件的上下文中知道该 bool 的状态,然后才能在其他任何地方访问它似乎已经纠正了这个问题。见下文:
    前:
    bool PDSync::Conv_ReadAvail(){
    if(Calc_isavailable && Conv_shouldread){
    return true;
    }else{
    return false;
    }
    }
    后:
    bool PDSync::Conv_ReadAvail(){
    bool temp = false;
    pthread_mutex_lock(&Calc_lock_mutex);
    if(Conv_shouldread){
    temp = true;
    }else{temp = false;}
    pthread_mutex_unlock(&Calc_lock_mutex);

    if(Calc_isavailable && temp){
    return true;
    }else{
    return false;
    }
    }
    读取重置 bool 值 Conv_shouldread = false 也被移回互斥保护器内部,以便它不能与 IF 条件触发器语句同时访问。
    应该注意的是,我在全局类的其他 3 个位置有类似的代码,它们从未遇到过有问题的竞争条件,但所有这些都传输了更少量的数据,所以我认为复制时间可能是这里的一个因素。无论哪种方式,我都会纠正它们,因为这样做是为了避免将来出现问题。谢谢大家的帮助!

    最佳答案

    您的问题的答案是:“不,仅在多线程上下文中。”
    在多线程环境中,几乎任何你无法想象的事情都会发生。您提供的背景和背景很广泛,但不足以研究这一点。
    一件事Conv_shouldread = false; //If true, Conv_ReadAvail returns true显然修改(或确定)if(ThreadSync.Conv_ReadAvail()) 的结果很明显,其他线程也在干扰这一点。因此,我会清楚地把 Conv_shouldread = false;在互斥保护里面。
    但除此之外,我必须承认问题可能明显存在于其他地方,并且不同线程之间可能存在很多副作用。

    关于c++ - 如果在触发 if 语句后触发条件失败,是否存在 IF 语句提前退出的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67085582/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com