通过共享内存使用 Thrift 进行 IPC 通信 [英] Using Thrift for IPC-Communication via shared Memory

查看:80
本文介绍了通过共享内存使用 Thrift 进行 IPC 通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找不到关于如何通过共享内存使用 apache thrift 进行 ipc 通信的充分示例.我的目标是在 thrift 的帮助下序列化一个现有的类,然后通过共享内存发送到另一个进程,在那里我在 thrift 的帮助下再次反序列化它.现在我正在使用 TMemoryBuffer 和 TBinaryProtocol 来序列化数据.虽然这有效,但我不知道如何将其写入共享内存.

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.

这是我目前的代码:

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

主要问题是部分

//myPtr = protocol.get();

我如何使用 thrift 以便我可以将反序列化的数据写入 myPtr(从而写入共享内存).我猜 TMemoryBuffer 可能已经是个坏主意.如您所见,我对此并没有真正的经验.

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

迈克尔

推荐答案

在再次阅读问题并仔细查看代码之后……您就差不多了.你犯的错误是查看协议,它没有给你任何数据.相反,您必须询问传输,就像您已经使用

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();

获取原始数据的方式非常相似,只需使用 getBuffer(&pbuf, &sz); 代替.使用这个,我们得到了这样的东西:

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

由于 shmget() 可能会为您提供比请求更大的块,因此额外使用 成帧传输 似乎是个好主意,它会自动携带序列化数据中的真实数据大小.后者的一些示例代码可以在 Test Client 中找到或服务器代码.

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.

这篇关于通过共享内存使用 Thrift 进行 IPC 通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆