有没有更好的方法来处理 C++ 中共享内存的竞争条件?

Chu*_*Lin 5 c++ synchronization shared-memory

我的应用程序中需要 IPC。我尝试过socket,但速度不够快。因此,我使用共享内存来做到这一点。为了同步通信,我使用内存中的标志并在 while 循环中检查它。它可以工作,但是轮询非常耗时,这使得它比套接字的解决方案慢。我的代码中共享内存的实现是shoom。我想在 Windows 和 Mac 上执行此操作,目前正在 Windows 上进行测试。完整的代码如下:

服务器:

#include "include/shoom.h"
#include <stdio.h>
#include <thread>

typedef struct _packet_ {
    uint8_t flag;
    int data;
} _packet;

int main()
{
    int data;
    _packet* ptr;
    shoom::Shm server("test", sizeof(_packet));

    if (server.Create() == shoom::kOK)
    {
        ptr = (_packet*)server.Data();

        while (1)
        {
            while (!ptr->flag)
            {
                std::this_thread::sleep_for(std::chrono::microseconds(100));
            }

            data = ptr->data;
            ptr->flag = 0;

            printf("%d\n", data);
        }
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

客户:

#include "include/shoom.h"
#include <stdio.h>
#include <chrono>
#include <thread>

typedef struct _packet_ {
    uint8_t flag;
    int data;
} _packet;

int main()
{
    std::chrono::system_clock::time_point ts, te;
    double t;

    _packet* ptr;
    
    int data;

    shoom::Shm client("test", sizeof(_packet));

    if (client.Open() == shoom::kOK)
    {
        ptr = (_packet*)client.Data();

        for (data = 1; data <= 100; data++)
        {
            
            ptr->flag = 1;
            memcpy(&ptr->data, &data, sizeof(data));
            
            ts = std::chrono::system_clock::now();

            while (ptr->flag)
            {
                std::this_thread::sleep_for(std::chrono::microseconds(100));
            }

            te = std::chrono::system_clock::now();
            t = (double)std::chrono::duration_cast<std::chrono::microseconds>(te - ts).count();

            printf("%lf\n", t);
        }
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

瓶颈是 while 循环。无论睡眠时间多长(<1ms),while循环的时间成本约为30ms。我检查过循环次数小于 3。

还有更好的解决办法吗?就像线程的条件变量一样。