c++ - 用 C++ 实现的可移植线程类

标签 c++ multithreading volatile

当编写需要在应用程序和中断例程/线程/回调例程之间共享文件范围变量的 C 程序时,众所周知,该变量必须声明为 volatile,否则编译器可能会不正确优化。这是我的意思的一个例子:

int flag;

void some_interrupt (void)
{
  flag = 1;
}



int main()
{
  flag = 0;
  ...

  /* <-- interrupt occurs here */

  x = flag; /* BUG: the compiler doesn't realize that "flag" was changed 
                    and sets x to 0 even though flag==1 */

}

为了防止上述错误,“flag”应该声明为 volatile。

我的问题是:在创建包含线程的类时,这如何适用于 C++?

我有一个看起来像这样的类:

class My_thread
{
  private:
    int flag;

    static void thread_func (void* some_arg) // thread callback function
    {
      My_thread* this_ptr= (My_thread*)some_arg;

    }
};

“some_arg”将包含一个指向类实例的指针,这样“My_thread”的每个对象都有自己的线程。通过这个指针,它将访问成员变量。

这是否意味着“this_ptr”必须声明为指向 volatile 数据的指针? “标志”也必须是易变的吗?如果是这样,我是否必须使所有修改“标志”的成员函数都可变?

我对特定操作系统或编译器的行为方式不感兴趣,我正在寻找一种通用的、完全可移植的解决方案。

编辑:这个问题与线程安全无关!

真正的代码会有信号量等

澄清一下,我希望避免因编译器不知道可能从程序本身以外的源调用回调函数而导致的错误,从而对是否使用了某些变量做出错误的结论。我知道如何在 C 中执行此操作,如第一个示例所示,但在 C++ 中不知道。

最佳答案

好吧,这个编辑让世界变得与众不同。信号量引入了内存屏障。这些使 volatile 变得多余。在对信号量进行任何操作后,编译器将始终重新加载 int flag

Fred Larson 已经预见到了这一点。 volatile 在没有锁的情况下是不够的,在有锁的情况下是冗余的。这使得它对于线程安全编程毫无用处。

关于c++ - 用 C++ 实现的可移植线程类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5107171/

相关文章:

使用返回模板声明接口(interface)的 C++ 错误

c++ - 在运算符表达式上下文中纠正重载解析的内置运算符候选的行为

c++ - `static_cast<volatile void>` 对优化器意味着什么?

java - Java 中的 volatile 关键字

c++ - 为什么 std::cout 将 volatile 指针转换为 bool?

使用命名空间创建 C++ 库

c++ - 保证在 pthread_wait_signal 之前执行 pthread_cond_wait

java - Android Studio Java 可运行未运行

Python:WAITING文件以 CPU 友好的方式达到大小限制

ios - AVURLAsset URLAssetWithURL :options: blocks main thread with remote URL?