0

I need to access a structure between different processes. Is there any way to copy a structure in to a shared memory and then access the same structure in some other process.(using POSIX standards)

My structure is

typedef struct binary_semaphore {
    pthread_mutex_t mutex;
    sem_t *sem;
} binary_semaphore;
3442
  • 8,248
  • 2
  • 19
  • 41
Abhishek Gangwar
  • 1,697
  • 3
  • 17
  • 29

2 Answers2

2

Do not even think of it !

If your structure just contained plain old data (integers, floating point numbers, characters or arrays of them) all would be fine: you get access to a share memory segment, copy the struct there with memcpy, and you can access it through any other process through the shared memory.

It becomes much more tricky as soon as the structure contains pointers to plain old data: you must copy the plain old data to shared memory, and replace the pointers with ids to shared memory, or offsets in a shared memory segment.

But here your struct contains a mutex and a pointer to a semaphore. They are by themselves inter process communication tools! Just get access to them from the other processes and use them directly.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
1

It depends on what type of handle you have.

If you have a void*...

memcpy(sharedMemory, &myStruct, sizeof(struct MyStruct));

If you have an int from int shm_open(const char*, int, mode_t)...

void *sharedMemory = mmap(NULL, mySharedMemorySize, PROT_READ | PROT_WRITE, MAP_SHARED, myIntFromShmOpen, 0);
memcpy(sharedMemory, &myStruct, sizeof(struct MyStruct));

If you have an int from int shmget(key_t, size_t, int)...

void *sharedMemory = shmat(myIntFromShmGet, NULL, 0);
memcpy(sharedMemory, &myStruct, sizeof(struct MyStruct));

Hope this helps!

3442
  • 8,248
  • 2
  • 19
  • 41
  • As the struct contains a pointer, you are copying the address of sem_t in first process. It will be correctly copied but will **definitely not** be useable in an other process – Serge Ballesta Aug 23 '15 at 10:45
  • I just happen to answer that same issue today (see http://stackoverflow.com/questions/32153151/how-to-create-semaphores-in-shared-memory-in-c/32154145#32154145). In other words, see [sem_init(3)](http://man7.org/linux/man-pages/man3/sem_init.3.html). In even more tl;dr words, `sem_init()` takes care of that. **Edit**: The actual use of `sem_init()` is found in the comments. – 3442 Aug 23 '15 at 10:49
  • That's what I meant in my comment: OP should **not** try to put a `sem_t *` in shared memory but directly use it from the other process. – Serge Ballesta Aug 23 '15 at 10:58
  • @KemyLand `sem_init` doesn't seem to take care of anything. The man page doesn't indicate that the function works by magic, which would be absolutely required to make a pointer located in shared memory work across processes. – n. m. could be an AI Aug 23 '15 at 10:59
  • 1
    I just want to acess the mutex part of the struct – Abhishek Gangwar Aug 23 '15 at 11:37
  • @n.m.: `sem_init(3)` *does* "magic". A simple [`semaphore.c`](http://pastebin.ca/3125250) probes it. @AbhishekGangwar: There won't be any problem if you do it as I described in this post. – 3442 Aug 23 '15 at 21:52
  • @KemyLand you are certainly entitled to your opinion, but no, it doesn't. – n. m. could be an AI Aug 24 '15 at 00:03
  • @n.m.: My opinion? I just probed it with source code! Compile and test it if you want. **Edit**: The OP's structure shall be modified to `typedef struct { pthread_mutext_t mutex; sem_t sem; } binary_semaphore;` for all this conversation to have the least sense. – 3442 Aug 24 '15 at 00:31
  • Your program first opens shared memory, then forks. A child inherits parent's shared memory. Everything is mapped to the same address. There is no magic there. You can set up any forest of pointers inside that memory and it will work. Now try to do the same with two unrelated processes. – n. m. could be an AI Aug 24 '15 at 00:34
  • @n.m.: Read the source carefully! What each process do have in common is a *file descriptor to shared memory that hasn't been mapped yet.* Each process does `mmap()` independent of one another, so (due to memory space randomization), they'll end up having the shared memory mapped at different virtual addresses. – 3442 Aug 24 '15 at 00:36
  • And for the sake of completeness. I tested the address at whichb oth processes matched the stuff, and they were the same address (is my kernel lazy today?). So I forced the second process to `mmap()` to a fixed address, and the program still works. Output: – 3442 Aug 24 '15 at 00:41
  • The parent's PID is 14670 The child's PID is 14671 Shared memory at 0x7f48abbe7000 Hi! I'm the first process in it's iteration #1! Shared memory at 0x7f0f78898000 Hi! I'm the second process in it's iteration #1! Hi! I'm the first process in it's iteration #2! Hi! I'm the second process in it's iteration #2! Hi! I'm the first process in it's iteration #3! – 3442 Aug 24 '15 at 00:42
  • Hi! I'm the first process in it's iteration #4! Hi! I'm the second process in it's iteration #3! Hi! I'm the second process in it's iteration #4! Hi! I'm the first process in it's iteration #5! Hi! I'm the second process in it's iteration #5! Hi! I'm the first process in it's iteration #6! Hi! I'm the second process in it's iteration #6! Hi! I'm the first process in it's iteration #7! Hi! I'm the second process in it's iteration #7! Hi! I'm the first process in it's iteration #8! Hi! I'm the second process in it's iteration #8! – 3442 Aug 24 '15 at 00:42
  • Sorry, your program doesn't keep the pointer in the shared memory. It doesn't do what you suggest in your answer, namely, `memcpy(sharedMemory, &myStruct, sizeof(struct MyStruct));` where `myStruct` contains a pointer to the semaphore. It doesn't test any magic. Read carefully: "magic, which would be absolutely required to make a **pointer located in shared memory** work across processes" – n. m. could be an AI Aug 24 '15 at 00:55
  • @m.n.: This conversation is getting out of the way. First of all, you're misunderstanding me/not reading 113 lines of code. My program **applies to, and only to a single `sem_t` that gets initialized in the shared memory area. I'm not talking about any class of pointers. And, I have, already said it, "The OP's structure shall be modified to typedef struct { pthread_mutext_t mutex; sem_t sem; } binary_semaphore; for all this conversation to have the least sense."**. – 3442 Aug 24 '15 at 01:02
  • Sorry, missed that remark. It should have been stated clearly in the answer. Now the conversation makes absolutely zero sense, because you don't copy semaphores or mutextes. You initialize them in shared memory in one process and just point to them in other processes. – n. m. could be an AI Aug 24 '15 at 01:12
  • @n.m.: Well, the OP's question is not perfect, and it is due to (more or less) another answer I gave him (http://stackoverflow.com/questions/32153151/how-to-create-semaphores-in-shared-memory-in-c/32154145#32154145), and the OP happened to rephrase it incorrectly. After all, initializing in one process, then using in others, is what shall be done. Copying syncher objects is completely irrelevant from what can be deducted from the OP's question. Anyway, if that would be the case, the copying could be done by initializing one of such objects with the value of another (see `sem_getvalue(3)`). – 3442 Aug 24 '15 at 01:23