草庐IT

c++ - 函数没有 volatile。怎么修?

coder 2024-02-21 原文

我在两个线程之间共享一个变量。我使用 volatile 来避免优化。

但是,它显示了一个错误,因为在 strcpy 中没有 volatile。 (如下)

如何正确修复此错误?

有人告诉我要通过类型抛弃 volatile。 但是,如果我抛弃了 volatile,那么我就失去了 volatile 的目的…… 最终可能会因优化而出现运行时错误......不是吗?

非常感谢。

(代码可以直接编译)


CRITICAL_SECTION CriticalSection;

HANDLE hEvent;

void __cdecl MyThread(void* name)

{

char serName[256];

volatile char* vptr = (char*) name;



EnterCriticalSection(&CriticalSection);



strcpy(serName, vptr); // error : cannot convert 'volatile'

// use (and not modify) name…



LeaveCriticalSection(&CriticalSection);

SetEvent (hEvent) ;

}




void main ()

{

char name[256] = "abcde";

hEvent = CreateEvent (NULL, false, false, NULL) ;

if (!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x80000400) )

return;



_beginthread (MyThread, 0, name) ;



EnterCriticalSection(&CriticalSection);

// access name…

LeaveCriticalSection(&CriticalSection);



WaitForSingleObject (hEvent, INFINITE) ;

DeleteCriticalSection(&CriticalSection);

CloseHandle (hEvent);

system("pause");

}

另一方面,我可以编写自己的 strcpy 来支持 volatile。 但这很奇怪。 因为如果是这样,那么我每次使用 volatile 时都必须编写自己的 I/O 流(或那些复杂的函数)?

再次感谢您的回答。

最佳答案

显然您对“volatile”的含义没有清楚的理解。意思或多或少是“嘿编译器,请注意其他人会改变这个变量,所以你不能假设除非你的代码写入它,否则值将保持不变。此外,其他人可能正在观察这个变量,所以当我写到这个变量请不要在假设无关紧要的情况下做奇怪的事情,因为对于其他观看它的人来说很重要,所以只要写下我想让你写的,当我告诉你写的时候。”

什么时候使用“volatile”很重要?这是一个常见的例子:

volatile int stopflag; // flag will be set by an interrupt handler

void mainloop()
{
    stopflag = 0;
    while (!stopflag)
    {
       ...
    }
}

如果三个点中的代码从不触及 stopflag 并且从不调用具有未知实现的函数,那么编译器可能会试图避免读取循环中的标志,因为查看代码本身似乎根本不需要读取变量...只需设置并永远循环。

另一种情况可能是:

extern volatile unsigned char outloc; // monitored by hardware

...
// emit a wave pulse
for (int x=0; x<256; x++)
    outloc = x;

如果没有 volatile,编译器可能会试图将 0xFF 写入该位置,而不是写入所有中间值。

请注意,在现代硬件上使用volatile 进行线程同步是不够的。在今天的计算机中,通常 CPU 是多核的,因此写入和读取不再是原子操作。虽然在过去(在单核 CPU 上)实际上通常可以使用 volatile 变量进行线程同步,但现在这是错误的。

您似乎确实有兴趣说明 buffer 确实被其他人读写,但在这种情况下,缓冲区的地址是公共(public)的,因此在函数的任何调用中(除非它是内联的)或具有已知的实现代码)编译器必须假定缓冲区内容可能已更改或将被未知代码读取。

我敢打赌,线程同步原语是以正确的方式声明的,以确保在您的情况下也是如此(即使 strcpy 是内联的)。

关于c++ - 函数没有 volatile。怎么修?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11643116/

有关c++ - 函数没有 volatile。怎么修?的更多相关文章

  1. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  2. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  5. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  6. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  7. ruby - Ruby 中的隐式返回值是怎么回事? - 2

    所以我开始关注ruby​​,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出

  8. ruby - 怎么来的(a_method || :other) returns :other only when assigning to a var called a_method? - 2

    给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R

  9. ruby-on-rails - 我该怎么办 :remote location validation with CarrierWave? - 2

    我在我的Rails3示例应用程序上使用CarrierWave。我想验证远程位置上传,因此当用户提交无效URL(空白或非图像)时,我不会收到标准错误异常:CarrierWave::DownloadErrorinImageController#createtryingtodownloadafilewhichisnotservedoverHTTP这是我的模型:classPaintingtrue,:length=>{:minimum=>5,:maximum=>100}validates:image,:presence=>trueend这是我的Controller:classPaintingsC

  10. 没有类的 Ruby 方法? - 2

    大家好!我想知道Ruby中未使用语法ClassName.method_name调用的方法是如何工作的。我头脑中的一些是puts、print、gets、chomp。可以在不使用点运算符的情况下调用这些方法。为什么是这样?他们来自哪里?我怎样才能看到这些方法的完整列表? 最佳答案 Kernel中的所有方法都可用于Object类的所有对象或从Object派生的任何类。您可以使用Kernel.instance_methods列出它们。 关于没有类的Ruby方法?,我们在StackOverflow

随机推荐