假设我有一个指向线程中某个结构的指针,我想通过管道将它传递给父进程。
例子:
MyType * someType;
然后我想投到someType
并void *
把它放在管道上。怎么做到呢?
虽然您可以物理地将指针传递给父进程,但该值对进程没有意义,最好的情况是立即崩溃。指针指示内存中对象的地址。这个地址只会在子进程的上下文中有效,并且会指向父进程中完全不同的对象。
您需要执行以下操作之一才能启用此方案
编辑
请注意,我的答案是在询问如何在子进程和父进程之间传递指针时写的。后来更新为线程。
另一种选择是将对象存储在共享内存中,然后将段 ID 传递给父进程。
然后父级可以附加到内存并访问/修改对象。
这提供了一些背景: http: //fscked.org/writings/SHM/shm.html
在此问题和您引用的其他问题之间阅读,您使用“父进程”来指代主进程线程,而“线程”是指在同一进程中创建的新线程。这会导致您对问题的思考和其他试图回答问题的人感到困惑。
在这种情况下,只有一个进程,它有两个线程。当操作系统启动进程时,为您创建了第一个线程。第二个是第一个故意创造的。您已决定使用管道在这些线程之间进行通信。
首先,我同意关于另一个问题的很多答案,即管道是线程间通信的一种重量级解决方案,因为它们旨在处理进程间通信。也就是说,他们会工作。
其次,请注意您将无法在进程之间有意义地移动指针。指针仅在单个进程中有效。甚至指向共享内存的指针也存在问题,因为共享内存区域可能会映射到每个进程中的不同虚拟地址。因为看起来管道的两端都在同一个进程中,所以这不是问题,但如果不是这样,那将是一个大问题。
考虑到所有这些,您只需要就指针的表示与自己达成一致。最简单的答案是只将sizeof(void *)
字节写入管道。读出时,您将这些字节放回指针变量中,然后转换回实际类型。当然,您周围的协议必须知道该类型是什么。
如果您想让两个线程存在于不同的进程中,或者重用此代码以将您正在进行的工作持久化(检查点)在一个文件中,那么您将遇到更复杂的问题。搜索有关数据和状态持久性、酸洗和封送处理的讨论会引发一些需要思考的事情。
Put it in shared memory, and pass a pointer relative to the shared memory base. Pointer casting depends on how your compiler aligns objects. An remember when getting relative pointer positions, pointer arithmetic is based on sizeof the thing pointed to.