2 years ago

#64383

test-img

Chun-Hsien Lin

Is there any better way to deal with race condition of shared memory in C++?

I need an IPC in my application. I'v tried socket, but its speed is not fast enough. Hence, I use shared memory to do that. To synchronize the communication, I use a flag in the memory and check it in a while-loop. It works, but the polling is time consuming which make it slower than the solution of socket. The implementation of shared memory in my code is shoom. I want to do that on both Windows and Mac, and I'm currently testing on Windows. The complete code is like:

Server:

#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;
}

Client:

#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;
}

The bottleneck is the while-loop. No matter how long the sleep time is (< 1ms), the time cost of the while-loop is about 30ms. I've checked the loop count is less than 3.

Is there any better solution? like condition variable for threading.

c++

synchronization

shared-memory

0 Answers

Your Answer

Accepted video resources