2

I am working on the dining philosopher's problem and can't use threads so I need to use shared memory to make the array of chopsticks and philosophers visible to all child processes. I am trying to use mmap, however, my use of mmap is incorrect and I am unsure how to fix it since my argument is an array of ints not an int as per this question. Should I be using a different function to make it in shared memory?

(declared at the global scope)
int chopsticks[5];
int sizeOfSticks=sizeof(int)*5;
void* map = mmap(0,sizeOfSticks,PROT_READ|PROT_WRITE, MAP_SHARED,chopsticks,0);
Community
  • 1
  • 1
CodeMonkey
  • 268
  • 5
  • 16

1 Answers1

3

The second-to-last argument to mmap() is a file descriptor, for cases where you're mapping a file into memory. If you just need to allocate some shared memory, then do this instead:

int *chopsticks;

...

chopsticks = mmap(NULL, N_CHOPSTICKS*sizeof(int),
                  PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED,
                  -1, 0);

MAP_ANONYMOUS means the mapping has no corresponding file. Passing 0 for fd is likely to work too, but -1 might be more portable (see e.g. the mmap(2) man page on Linux).

The mapping will be inherited by fork(2)'d child processes.

As a small style side note, you could write N_CHOPSTICKS*sizeof(*chopsticks) instead of N_CHOPSTICKS*sizeof(int). That way the size will still be correct even if you change the type of chopsticks.

Ulfalizer
  • 4,664
  • 1
  • 21
  • 30
  • Thank you for your answer, I implemented this and it is throwing an error saying that "initializer element is not consistent" – CodeMonkey Mar 25 '15 at 00:09
  • @CodeMonkey: Did you write `int *chopsticks = mmap(...)` and not `int chopsticks[5] = mmap(...)`? `chopsticks` will have to be a pointer. – Ulfalizer Mar 25 '15 at 00:12
  • yes, my line is `int* chopsticks=mmap(NULL, STICKS*sizeof(int),PROT_READ| PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);` where STICKS is defined as 5 at the global – CodeMonkey Mar 25 '15 at 00:17
  • @CodeMonkey: On what line are you getting that error? Did you remove the original `int chopsticks[5]` too? – Ulfalizer Mar 25 '15 at 00:20
  • @CodeMonkey: If you want to, you could paste your current code to pastie.org. Less guessing that way. – Ulfalizer Mar 25 '15 at 00:21
  • The line itself is fine, so it has to be another issue in your code. – Ulfalizer Mar 25 '15 at 00:21
  • @CodeMonkey: Ahhh... just noticed you're declaring things at global scope. What you need to do instead is to have a separate `int *chopsticks;` declaration globally, and do `chopsticks = mmap(...)` inside your function. Sorry for missing that! You can't call functions in initializers for global objects. *(Edited the answer now too.)* – Ulfalizer Mar 25 '15 at 00:23
  • (That's assuming you really need to have it globally. Otherwise, you could make it local too. :) – Ulfalizer Mar 25 '15 at 00:24
  • I implemented these changes but now I am getting the error "data definition has no type or storage class [enabled by default]" I declared `int*chopsticks` at the global and declared inside my main (as the first line) ` chopsticks=mmap(NULL, STICKS*sizeof(int),PROT_READ| PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);` – CodeMonkey Mar 25 '15 at 00:34
  • @CodeMonkey: Probably easiest if you paste your code on pastie.org and link it here in the comments so I can see it. – Ulfalizer Mar 25 '15 at 00:35
  • You didn't forget the semicolon at the end of `int *chopsticks`, right? – Ulfalizer Mar 25 '15 at 00:36
  • There are other errors as well, but I am just trying to get the mapping to work. Would it be easier to do shmget and the functions regarding that – CodeMonkey Mar 25 '15 at 00:39
  • @CodeMonkey: Note that the error is on the `int semId = semget(...)` line. You can't call `semget(2)` when initializing a global variable. (That's why the error message complains that the initializer is not constant.) I recommend that you use POSIX semaphores by the way (e.g., `sem_init(3)`), as they're much simpler (you're currently using System V semaphores), but you would need to read up on how to use them though. – Ulfalizer Mar 25 '15 at 00:45
  • Sorry for the self-plug, but there's an example at http://stackoverflow.com/a/29226417/4577158 by the way. (Write the `mmap()` like in the answer here instead -- the example in the linked answer uses a mechanism you probably don't need). This is pretty heavy stuff if you're really new to C though. The `mmap()` in my answer is correct at least. – Ulfalizer Mar 25 '15 at 00:50