C ++ 11原子是T吗?可用于mmap吗? [英] Is C++11 atomic<T> usable with mmap?

查看:70
本文介绍了C ++ 11原子是T吗?可用于mmap吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想添加对Linux嵌入式系统上运行的服务(守护程序)使用的少数参数的网络控制.不需要过程调用,可以以非常自然的方式轮询每个参数.共享内存似乎是一种很好的方式,可以将网络代码保留在守护程序之外,并限制对一组精心控制的变量的共享访问.

I want to add network control of a handful of parameters used by a service (daemon) running on a Linux embedded system. There's no need for procedure calls, each parameter can be polled in a very natural way. Shared memory seems a nice way to keep networking code out of the daemon, and limit shared access to a carefully controlled set of variables.

由于我不希望部分写入引起从未写入的值的可见性,因此我考虑使用std::atomic<bool>std::atomic<int>.但是,我担心std::atomic<T>的实现方式可能仅适用于C ++ 11线程,而不适用于多个进程(可能甚至不适用于OS线程).具体来说,如果实现使用共享内存块外部存储的任何数据结构,则在多进程方案中,这将失败.

Since I don't want partial writes to cause visibility of values never written, I was thinking of using std::atomic<bool> and std::atomic<int>. However, I'm worried that std::atomic<T> might be implemented in a way that only works with C++11 threads and not with multiple processes (potentially, not even with OS threads). Specifically, if the implementation uses any data structures stored outside the shared memory block, in a multi-process scenario this would fail.

我确实看到了一些要求,这些要求表明std::atomic不会保存嵌入式锁对象或指向其他数据的指针:

I do see some requirements which suggest to be that std::atomic won't hold an embedded lock object or pointer to additional data:

原子积分专长和专长atomic<bool>应具有标准布局.它们每个都有一个普通的默认构造函数和一个普通的析构函数.它们每个都应支持聚合初始化语法.

The atomic integral specializations and the specialization atomic<bool> shall have standard layout. They shall each have a trivial default constructor and a trivial destructor. They shall each support aggregate initialization syntax.

应该有原子类模板的指针部分专业化.这些专业应具有标准布局,琐碎的默认构造函数和琐碎的析构函数.它们均应支持聚合初始化语法.

There shall be pointer partial specializations of the atomic class template. These specializations shall have standard layout, trivial default constructors, and trivial destructors. They shall each support aggregate initialization syntax.

在我看来,临时默认构造和销毁方式排除了相关的按对象数据,无论是通过指针成员变量还是通过外部映射存储在对象内部.

Trivial default construction and destruction seems to me to exclude associated per-object data, whether stored inside the object, via a pointer member variable, or via an external mapping.

但是,我发现没有什么可以排除使用单个全局互斥锁/关键部分(甚至是全局集合)的实现,只要集合元素不与单个原子对象相关联-类似于缓存关联方案可用于减少错误冲突).显然,在使用全局互斥锁的实现中,来自多个进程的访问将失败,因为用户将具有独立的互斥锁,并且实际上彼此之间没有同步.

However, I see nothing that excludes an implementation from using a single global mutex / critical section (or even a global collection, as long as the collection elements aren't associated with individual atomic objects -- something along the lines of a cache association scheme could be used to reduce false conflicts). Obviously, access from multiple processes would fail on an implementation using a global mutex, because the users would have independent mutexes and not actually synchronize with each other.

atomic<T>的实现是否被允许做与进程间共享内存不兼容的事情,或者是否有其他使其安全的规则?

Is an implementation of atomic<T> allowed to do things that are incompatible with inter-process shared memory, or are there other rules that make it safe?

我刚刚注意到,琐碎的默认构造使对象处于未就绪状态,因此需要调用atomic_init.标准提到了锁的初始化.如果将它们存储在对象内部(由于析构函数仍然微不足道,则动态内存分配似乎是不可能的),那么它们将在进程之间共享.但是我仍然担心全局互斥的可能性.

I just noticed that trivial default construction leaves the object in a not-ready state, and a call to atomic_init is required. And the Standard mentions initialization of locks. If these are stored inside the object (and dynamic memory allocation seems impossible, since the destructor remains trivial) then they would be shared between processes. But I'm still concerned about the possibility of a global mutex.

无论如何,要保证对共享区域中的每个变量的atomic_init进行单个调用似乎很困难...因此,我想我必须避开C ++ 11原子类型.

In any case, guaranteeing a single call to atomic_init for each variable in a shared region seems difficult... so I suppose I'll have to steer away from the C++11 atomic types.

推荐答案

我迟到了两个月,但是现在我遇到了完全相同的问题,我想我已经找到了某种答案.简短的版本是它应该可以工作,但是我不确定是否要依赖它.

I'm two months late, but I'm having the exact same problem right now and I think I've found some sort of an answer. The short version is that it should work, but I'm not sure if I'd depend on it.

这是我发现的东西:

  • C ++ 11标准定义了一个新的内存模型,但是它没有操作系统级进程"的概念,因此任何与多处理相关的都是非标准的.

  • The C++11 standard defines a new memory model, but it has no notion of OS-level "process", so anything multiprocessing-related is non-standard.

但是,该标准(或至少我拥有的草案N3337)的第29.4节无锁属性"以以下注释结尾:

However, section 29.4 "Lock-free property" of the standard (or at least the draft I have, N3337) ends with this note:

[注意:无锁的操作也应无地址.也就是说,原子操作在同一 通过两个不同地址的内存位置将自动进行通信.实施不应该 取决于任何每个进程的状态.此限制允许通过映射到内存中的内存进行通信. 一个以上的进程和两个进程之间共享的内存. —尾注]

[ Note: Operations that are lock-free should also be address-free. That is, atomic operations on the same memory location via two different addresses will communicate atomically. The implementation should not depend on any per-process state. This restriction enables communication by memory that is mapped into a process more than once and by memory that is shared between two processes. — end note ]

这听起来很有希望. :)

This sounds very promising. :)

该注释似乎来自 N2427 ,甚至更为明确:

That note appears to come from N2427, which is even more explicit:

为便于通过共享内存进行进程间通信,我们的目的是无锁操作也应无地址.也就是说,通过两个不同的地址对同一内存位置进行的原子操作将进行原子通信.实现不应依赖于任何每个进程的状态.尽管这样的定义超出了标准的范围,但是明确说明我们的意图将使已经存在的程序类的可移植表达成为可能.

To facilitate inter-process communication via shared memory, it is our intent that lock-free operations also be address-free. That is, atomic operations on the same memory location via two different addresses will communicate atomically. The implementation shall not depend on any per-process state. While such a definition is beyond the scope of the standard, a clear statement of our intent will enable a portable expression of class of a programs already extant.

看来,是的,所有无锁操作都应该在这种确切的情况下起作用.

So it appears that yes, all lock-free operations are supposed to work in this exact scenario.

现在,std::atomic<type>上的操作是原子性的,但对于特定的type,它们可能是无锁的,也可能不是无锁的,具体取决于平台的功能.我们可以通过调用x.is_lock_free()来检查任何变量x.

Now, operations on std::atomic<type> are atomic but they may or may not be lock-free for particular type, depending on capabilities of the platform. And We can check any variable x by calling x.is_lock_free().

那我为什么写我不依赖于此呢?我找不到gcc,llvm或任何其他与此相关的文档.

So why did I write that I would not depend on this? I can't find any kind of documentation for gcc, llvm or anyone else that's explicit about this.

这篇关于C ++ 11原子是T吗?可用于mmap吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆