繁体   English   中英

IPC通过与atomic_t共享的内存进行; 对x86有好处吗?

[英]IPC through shared memory with atomic_t; is it good for x86?

我有以下代码用于通过共享内存进行进程间通信。 一个进程写入日志,另一个进程从其读取。 一种方法是使用信号量,但这里我使用的是驻留在共享内存中的atomic_t类型的原子标志( log_flag )。 日志( log_data )也被共享。

现在的问题是,这是否适用于x86架构,还是我需要信号量或互斥量? 如果我将log_flag设为非原子怎么办? 鉴于x86具有严格的内存模型和主动缓存一致性,并且没有对指针进行优化,我认为它仍然可以工作吗?

编辑 :请注意,我有一个具有8核的多核处理器,因此在这里忙碌等待没有任何问题!

// Process 1 calls this function
void write_log( void * data, size_t size )
{
    while( *log_flag )
           ;
    memcpy( log_data, data, size );
    *log_flag = 1;
}

// Process 2 calls this function
void read_log( void * data, size_t size )
{
    while( !( *log_flag ) )
       ;
    memcpy( data, log_data, size );
    *log_flag = 0;
}

您可能需要在循环中使用以下宏,以避免增加内存总线的压力:

#if defined(__x86_64) || defined(__i386)
#define cpu_relax() __asm__("pause":::"memory")
#else
#define cpu_relax() __asm__("":::"memory")
#endif

此外,它还充当内存屏障( "memory"参数),因此无需将log_flag声明为volatile

但是我认为这太过分了,应该只对硬实时内容执行。 使用futex应该没问题。 也许您可以简单地使用管道,它几乎可以满足所有用途的需求。

我不建议这样做有两个原因:首先,尽管编译器可能无法优化指针访问,但这并不意味着处理器不会缓存该指向的值。 其次,它是原子的事实不会阻止while循环的末尾与执行* log_flag = 0的行之间的读取访问。 互斥锁更安全,但速度要慢得多。

如果您使用的是pthread,请考虑使用RW互斥锁来保护整个缓冲区,这样就不需要标记来对其进行控制,互斥锁本身就是该标记,并且在进行频繁读取时会具有更好的性能。

我也不建议执行空的while()循环,那样会占用所有处理器。 将usleep(1000)放入循环中,使处理器有机会呼吸。

有很多原因导致您应该使用信号量而不依赖标志。

  1. 您的while循环读取日志不必要地旋转。 这不必要地消耗了系统资源,例如电力。 这也意味着CPU不能用于其他任务。
  2. 如果x86完全保证读写顺序,我会感到惊讶。 传入数据可能仅将日志标志设置为1,而传出数据将其设置为0。这可能意味着您最终会丢失数据。
  3. 我不知道您从哪里得到的优化不是一般用途的指针。 优化可以应用于与外部更改没有差异的任何地方。 编译器可能不知道log_flag可以被并发进程更改。

问题2可能看起来很可能很少出现,并且很难找到问题所在。 因此,请帮自己一个忙,并使用正确的操作系统原语。 他们将保证一切正常。

只要log_flag是原子的,就可以了。

如果log_flag只是常规布尔值,则不能保证它会起作用。

编译器可能会重新排序您的指令

*log_flag = 1;
memcpy( log_data, data, size );

这在单处理器系统上在语义上是相同的,只要未在memcpy内部访问log_flag即可。 您唯一可以节省的宽限可能是劣质的优化程序,它无法推断出在memcpy中访问了哪些变量。

CPU可以重新排序您的指令
它可以选择在循环之前加载log_flag以优化管道。

缓存可能会重新排序您的内存写入。
包含log_flag的缓存行可能会在包含data的缓存行之前与其他处理器同步。

您需要的是一种告诉编译器,cpu和缓存“递归”的方法,以使他们不必对顺序进行假设。 那只能用内存栅栏来完成。 std::atomicstd::mutex和semaphore均在其代码中嵌入了正确的内存防护指令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM