views:

308

answers:

4

Say I have a pointer to some structure in a thread, and I want to pass it to the parent process via a pipe.


Example:

MyType * someType;

I then want to cast someType to void * and put it on the pipe. How can it be done?

+13  A: 

While you can physically pass a pointer to a parent process, the value would be meaningless to the process and your best case scenario would be an immediate crash. Pointers indicate an address of an object in memory. This address will only be valid in the context of the child process and will point to a completely different object in the parent process.

You'll need to do one of the following in order to enable this scenario

  • Pass the entire object across the pipe in some serialized from
  • Pass a pointer relative to the shared memory base between the processes and do the appropriate fixup in the parent process.

EDIT

Note, my answer was written when the question was asking about how to pass a pointer between a child and parent process. It was later updated to threads.

JaredPar
Passing a pointer to shared memory won't work because the shared memory segment is not necessarily mapped at the same base address in both processes.
zvrba
@zvrba, clarified the wording to account for different base address differences between the shared memory in the two processes
JaredPar
You need to pass the offset from the base address of the section, then it will work. Also, the former approach of serialization will be *much* easier to get right, and much less scary
Paul Betts
He did say *thread*... if he actually means thread, then they actually do share memory, and the pointer would be legitimate.
Chris Arguin
@Chris, check the history on the question. The original question said process instead of thread.
JaredPar
+4  A: 

Another option would be to store the object in shared memory, then pass the segment ID to the parent process.

The parent can then attach to the memory and access/modify the object.

This gives some background: http://fscked.org/writings/SHM/shm.html

+1  A: 

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.

Charlie
+1  A: 

Reading between the lines in this and the other question you cite, you are using "parent process" to refer to the main process thread, and "thread" to refer to a new thread created within that same process. This is causing confusion both for your thinking about the problem and for others trying to answer the questions.

In this scenario, there is exactly one process, and it has two threads. The first thread was created for you when the OS started the process. The second was created deliberately by the first. You have decided to use pipes to communicate between these threads.

First, I'd agree with a lot of the answers on the other question that pipes are a bit of a heavy-weight solution to inter-thread communication since they were designed to handle inter-process communication. That said, they will work.

Second, be aware that you won't be able to meaningfully move a pointer between processes. Pointers are only valid within a single process. Even pointers to shared memory have issues since the shared memory regions might be mapped to different virtual addresses in each process. Since it looks like both ends of the pipe are in the same process, this isn't an issue, but if that weren't true, it would be a big issue.

With all of that in mind, you then just need to agree with yourself on a representation for the pointer. The simplest answer is to just write sizeof(void *) bytes to the pipe. When read out, you put those bytes back into a pointer variable, and cast back to the real type. Your surrounding protocol must know what that type is, of course.

If you become tempted to let the two threads exist in separate processes, or to reuse this code to persist (checkpoint) your work in progress in a file, then you have a more complicated problem. Searching for discussions of data and state persistence, pickling, and marshaling will lead to things to think about.

RBerteig