Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将易失性数据与不重载易失性数据的方法一起使用_C++_Gcc_Shared Memory_Systemc - Fatal编程技术网

C++ 将易失性数据与不重载易失性数据的方法一起使用

C++ 将易失性数据与不重载易失性数据的方法一起使用,c++,gcc,shared-memory,systemc,C++,Gcc,Shared Memory,Systemc,我的知识有点用完了 我有三个进程通过共享内存段进行通信。并发访问是通过正确的锁定来处理的(以避免在这里被误解),所以我很确定我使用的是volatile关键字 我的共享内存段被转换为指向结构的易失性指针,我可以对此进行操作。结构必须是易失性的,因为有时我需要旋转,直到共享内存中的某个值发生变化——所以不使用volatile不是一个选项 现在我正在使用一个外部C++库(SystemC,但在这里这不重要),我的结构包含sc_time的成员。虽然我可以访问库的源代码,但我不想依赖于我所做的修改,可能会破

我的知识有点用完了

我有三个进程通过共享内存段进行通信。并发访问是通过正确的锁定来处理的(以避免在这里被误解),所以我很确定我使用的是volatile关键字

我的共享内存段被转换为指向结构的易失性指针,我可以对此进行操作。结构必须是易失性的,因为有时我需要旋转,直到共享内存中的某个值发生变化——所以不使用volatile不是一个选项

现在我正在使用一个外部C++库(SystemC,但在这里这不重要),我的结构包含sc_time的成员。虽然我可以访问库的源代码,但我不想依赖于我所做的修改,可能会破坏一些东西,或者陷入维护的地狱

现在这个类“sc_time”有用于比较和赋值的运算符。这些操作符不使用易变的sc_时间-到目前为止并不令人惊讶

现在我的问题是:有没有一种方法可以在不破坏语义的情况下转换掉这种易变性?我可以使用经常提到的const_cast或简单的C-cast,但是编译器会做什么呢?我甚至可以只使用memcpy()来存储数据,但话说回来,结果会是什么呢

任何建议都是受欢迎的——我使用C-only包装器或任何其他方法都不会有任何问题——只要它能工作(tm),但我最后的办法是使用一些类似于memcpy的汇编代码来真正读取数据——这是我想要避免的

感谢您花时间阅读此文章:-)

编辑:添加了小代码段:

struct shared_memory{
     sc_time time1;
     sc_time time2;
     sc_time time3;
     ...
}

...

class foo 
{
    foo();   // attach shared memory and assign to *mem
    ...
    pthread_mutex_t mutex;
    volatile struct shared_memory *mem;
    ...
    void do_stuff();  // periodically called
};

void foo::do_stuff()
{
   ...
   lock_mutex(mutex);
   sc_time t1 = mem->time1;
   sc_time t2 = mem->time2;
   sc_time t3 = mem->time3;
   unlock_mutex(mutex);
   ... 
   while(t1 < t2 || t1 < t3){
       lock_mutex(mutex);
       t1 = mem->time1;
       t2 = mem->time2;
       t3 = mem->time3;
       unlock_mutex(mutex);
   }

}
struct共享内存{
sc_时间1;
sc_时间2;
sc_时间3;
...
}
...
福班
{
foo();//附加共享内存并分配给*mem
...
pthread_mutex_t mutex;
volatile struct shared_memory*mem;
...
void do_stuff();//定期调用
};
void foo::dou stuff()
{
...
锁定互斥体(互斥体);
sc_时间t1=mem->time1;
sc_时间t2=mem->time2;
sc_时间t3=mem->time3;
解锁_互斥体(互斥体);
... 
而(t1time1;
t2=mem->time2;
t3=内存->时间3;
解锁_互斥体(互斥体);
}
}

您可以使用const_cast来消除变量的“volatile”和“const”


注意:编译器将函数中的变量视为非易失性:)

如果必须旋转等待变量的更改,则未正确锁定。自旋等待始终必须假定对数据的原子访问。这不仅关系到获取最新版本的数据,还关系到一致性,例如,数据可能被分割到多个缓存线上,您可能只会获取旧版本的低字节和更新版本的高字节

由于这个原因,新的C和C++标准有原子访问的概念和工具,如果可能的话,使用它们。如果您没有,请使用编译器(或库)扩展:所有现代处理器都有原子指令,任何像样的编译器都有提供此类功能的扩展

使用
volatile
玩游戏不是你应该走的路。如果您丢弃了一个
volatile
,并将这样一个对象传递给一个函数,而该函数不希望在它下面发生任何变化,那么所有事情都可能发生。特别是,当编译了不具有
volatile
的库时,可以执行破坏数据的优化。不要这样做


编辑:因为你也用gcc标记了你的问题,所以他们有一个很好的理由,从很久以来就把
\uuu sync\u lock\u test\u和\u set
内置作为扩展。使用它。也许在您特定的体系结构组合上,这将在完全相同的代码中解决,但请相信gcc人员,他们知道何时必须添加一些汇编程序魔术来保证您的数据。

因此基本上您有
volatile sc_time timeVar(sc_time timeTmp)
,你的编译器抱怨类型不匹配,你想避免这种情况吗?此外,您传递非易失性变量的函数可能会优化变量,以便在执行过程中如果变量发生更改,它可能不会使用这些更改,您是否关心这些更改?无论如何,访问都是通过互斥锁进行检测的-因此,在它可以更改之前,互斥锁必须解锁-因此这不会发生。此外,我只需确保始终获得该值即可正确读取-所有同步,尽管如此复杂,在这里并不是我的问题。我知道这一点-但volatile语义会发生什么?读取是否仍会像是一个不稳定的过程?如果不是,我就不会赢任何东西。@Michael嗯。。。我不知道你在这里的真正意思。您的问题表明您已经读取了一个易失性变量值(编译器将其作为易失性变量处理),然后将其传递给一个非易失性函数,在该函数中您希望消除易失性。。。这是独立于读取的(不受后面的强制转换的影响)。。。也许可以添加一个代码片段?继续使用上面的易失性sc_time timeVar,我想做如下事情:…=新的sc_时间(timeVar),我不能。当我了解到一件事时,不仅仅是为了使编译器满意而强制转换某些东西,而是为了得到干净的解决方案——其他一切最终都会造成一个巨大的、丑陋的混乱。啊,所以sc_time的构造函数采用了一种类型的
sc_time
(非易失性),而您正试图获取一个单独的非易失性timeVar副本。。所以:
timenovol=new sc_time(const_cast(timeVar))这与我在“注释”中提到的没有什么不同。您的timeVar在其他地方保持“易失性”,但传入的值被视为(强制转换)非易失性。。。没有什么特别“混乱”的:)这仍然不能真正让我快乐,艾尔