簡體   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