提升进程间offset_ptr和提升数据传输线程

时间:2013-03-06 21:13:03

标签: c++ boost boost-thread boost-interprocess

我正在尝试使用boost的托管共享内存设置一个用于写入连续字节信息(int)的系统。这是我班级的精简版:

class PACKET_INFO
{
private:

offset_ptr<char> data[10];  // data pointers for various IPC threads to create transfer blocks. 

public:

int Put(void * src,int to,int from,int type,int size); //write
bool message_sig; // Received message
    int datasize; 
int Get(void * dest,int ID); //Read
boost::interprocess::interprocess_mutex      mutex;

};

int PACKET_INFO :: Put(void * src,int to,int size)
{
   managed_shared_memory managed_shm(open_only, "SHM_test");
   if(message_sig) return 0; //If there's already a message waiting, don't do anything
   scoped_lock<interprocess_mutex> lock(mutex,try_to_lock);
   if(!lock) return 0;
   data[to] = (char *)managed_shm.allocate(size*sizeof(int));
   memcpy(data[to].get(),src,size*sizeof(int)); 
   message_sig = true;
   datasize = size;
}

int PACKET_INFO :: Get(void * dest,int ID)
{
   managed_shared_memory managed_shm(open_only, "SHM_test");
   scoped_lock<interprocess_mutex> lock(mutex,try_to_lock);
    if(!lock) std::cout << "Will fail to read!" << std::endl;
   memcpy(dest,data[ID].get(),datasize*sizeof(int));
   message_sig = false; //Reset after receiving.
   datasize = 0;
   managed_shm.deallocate(data[ID].get()); //release memory
}

我使用其他数据成员(未显示)在写入和接收数据之前执行完整性检查。一切都按计划进行。当两个并行进程(A和B)运行时,A总是创建托管共享内存对象“SHM_test”并使用Put函数将数据写入B.这是通过将所需大小分配给特定offset_ptr并对其执行memcpy来完成的。 。 B使用Get函数读取此数据,并相应地返回特定offset_ptr中的数据。

现在,只要我看到这些函数被两个常规的单独进程调用,这就完美无缺。但是,当我运行使用Put函数的A的线程版本时,它运行良好约29/30次。在某种程度上,我在进程B中遇到了一个段错误,指出了memcpy错误。关于B的进一步调试我得到了:

(gdb) print data[ID]
$8 = {internal = {m_offset = 18446744073690921056, alignment_helper = {data_ = {buf = "`\270\343\376\377\377\377\377", 
    align_ = {<No data fields>}}}}}
(gdb) print data[ID].get()
$9 = 0x7ffff346c3d0 <Address 0x7ffff346c3d0 out of bounds>

这表明offset_ptr的地址不在流程的合法范围内。为了满足,我同时调试了进程A:

(gdb) print Packet->data[ID] 
$3 = {internal = {m_offset = 18446744073690921056, alignment_helper = {data_ = {buf = "`\270\343\376\377\377\377\377", align_ = {<No data fields>}}}}}
(gdb) print Packet->data[ID].get()
$4 = 0x7ffff3c293d0 ""

其中,Packet是PACKET_INFO类的对象。这个对象被进程A构建为共享内存中的命名对象,并由进程B在共享内存中找到。通过查看GDB的输出,偏移量明显匹配......意味着它应该可以工作!但我真的无法弄清楚为什么在线程进程A的情况下,这会导致进程B的offset_ptr超出界限。

我知道这是问题的一个非常简化的版本,但我希望它足以用于诊断或建议。

编辑:警告! 由于进程A的线程运行put函数并成功返回,因此我无法在线程点调试A. A的调试信息来自父进程。

0 个答案:

没有答案