Using Thrift for IPC-Communication via shared Memory

吃可爱长大的小学妹 提交于 2019-12-06 12:12:13

问题


I couldn't find a sufficient example on how to use apache thrift for ipc-communication via shared memory. My goal is to serialize an exisiting class with help of thrift, then send via shared memory to a different process where i deserialize it again with help of thrift. Right now i'm using TMemoryBuffer and TBinaryProtocol to serialize the data. Although this works, I have no idea on how to write it to shared memory.

Here is my code so far:

#include "test_types.h"
#include "test_constants.h"
#include "thrift/protocol/TBinaryProtocol.h"
#include "thrift/transport/TBufferTransports.h"

int main(int argc, char** argv)
{
    int shID;
    char* myPtr;
    Person* dieter = new Person("Dieter", "Neuer");
    //Person* johann = new Person("Johann", "Liebert");
    //Car* ford = new Car("KLENW", 4, 4);

    PersonThrift dieterThrift;
    dieterThrift.nachName = dieter->getNachname();
    dieterThrift.vorName = dieter->getVorname();

    boost::shared_ptr<apache::thrift::transport::TMemoryBuffer> transport(new apache::thrift::transport::TMemoryBuffer);
    boost::shared_ptr<apache::thrift::protocol::TBinaryProtocol> protocol(new apache::thrift::protocol::TBinaryProtocol(transport));

    test thriftTest;
    thriftTest.personSet.insert(dieterThrift);

    u_int32_t size = thriftTest.write(protocol.get());



    std::cout << transport.get()->getBufferAsString();

    shID = shmget(1000, 100, IPC_CREAT | 0666);
    if (shID >= 0)
    {
        myPtr = (char*)shmat(shID, 0, 0);

        if (myPtr==(char *)-1)
        {
            perror("shmat");
        }
        else
        {
            //myPtr = protocol.get();
        }
    }
    getchar();
    shmdt(myPtr);
}

The main problem is the part

//myPtr = protocol.get();

How do I use thrift so that I can write my deserialized data into myPtr (and thus into shared memory). I guess TMemoryBuffer might already be a bad idea. As you may see, I'm not really experienced with this.

Kind regards and thanks in advance

Michael


回答1:


After reading the question again and having a closer look at the code ... you were almost there. The mistake you made is to look at the protocol, which gives you no data. Instead, you have to ask the transport, as you already did with

std::cout << transport.get()->getBufferAsString();

The way to get the raw data is quite similar, just use getBuffer(&pbuf, &sz); instead. Using this, we get something like this:

// query buffer pointer and data size
uint8_t* pbuf; 
uint32_t sz; 
transport.get()->getBuffer(&pbuf, &sz);

// alloc shmem blöock of adequate size
shID = shmget(1000, sz, IPC_CREAT | 0666);
if (shID >= 0)
{
    myPtr = (char*)shmat(shID, 0, 0);

    if (myPtr==(char *)-1)
    {
        perror("shmat");
    }
    else
    {
       // copy serialized data into shared memory
        memcpy( myPtr, pbuf, sz);  
    }
}

Since shmget() may give you a larger block than requested, it seems to be a good idea to additionally use the framed transport, which automatically carries the real data size in the serialized data. Some sample code for the latter can be found in the Test Client or server code.



来源:https://stackoverflow.com/questions/25546348/using-thrift-for-ipc-communication-via-shared-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!