|
From: hugo.arregui on 3 Jul 2008 14:53 Hi! I have two struts like that: struct { int num; int num2; struct b arrayOfB[SIZE]; } a; struct { int num3; int num4 } b; I put struct a into Shared Memory: shmid = shmget(IPC_PRIVATE, sizeof(struct b), 0666) and atach it in two process: ptr = shmat(shmid, 0, 0); This works fine, but now i must delete the constant SIZE: I will obtain the SIZE in runtime, before execute the shmget function. the new struct a: struct { int num; int num2; struct b *arrayOfB; } a; now: I put struct a into Shared Memory: shmid = shmget(IPC_PRIVATE, sizeof(struct a) + sizeof(struct b) * size, 0666); and atach it in two process: ptr = shmat(shmid, 0, 0); my question is: how can tell arrayOfB to point over the shared memory? i thought: struct a *ptr,p2*; p2 = ptr; //ptr is the shmat return p2++; ptr->arrayOfB but doesn't work. in another way i read about the shmat parametrs, but don't understand how (if its possible) use to solve my trouble. Thanks.
From: ppi on 3 Jul 2008 16:54 > the new struct a: > > struct { > int num; > int num2; > struct b *arrayOfB; > > } a; > > now: > > I put struct a into Shared Memory: > shmid = shmget(IPC_PRIVATE, sizeof(struct a) + sizeof(struct b) * > size, 0666); > > and atach it in two process: > ptr = shmat(shmid, 0, 0); > > my question is: how can tell arrayOfB to point over the shared memory? you cannot do that: for each process thw shared memory will be mapped to a different address, hence storing pointers values inside the shared memory segment is useless: 0x12345678 for process A, and 0x87654321 for process B. > > but doesn't work. in another way i read about the shmat parametrs, but > don't understand how (if its possible) use to solve my trouble. You can try to use something like the mesg V queues trick i.e. struct { int num; int num2; struct b arrayOfB[1]; } a; shmid = shmget(IPC_PRIVATE, sizeof(struct a) + sizeof(struct b) * (size - 1), 0666); I do not remember if there is a padding/alignment issue there though. Maybe another poster could clarify that ? cheers, -- paulo
From: Jens Thoms Toerring on 3 Jul 2008 17:13 hugo.arregui(a)gmail.com <hugo.arregui(a)gmail.com> wrote: > Hi! > I have two struts like that: > struct { > int num; > int num2; > struct b arrayOfB[SIZE]; > } a; I guess you mean struct a { int num; int num2; struct b arrayOfB[SIZE]; }; and > struct { > int num3; > int num4 > } b; struct b { int num3; int num4 }; (and b must come before a if you want to create an array of b's in a). > I put struct a into Shared Memory: > shmid = shmget(IPC_PRIVATE, sizeof(struct b), 0666) > and atach it in two process: > ptr = shmat(shmid, 0, 0); > This works fine, but now i must delete the constant SIZE: > I will obtain the SIZE in runtime, before execute the shmget function. > the new struct a: > struct { > int num; > int num2; > struct b *arrayOfB; > } a; Again, make that struct a { int num; int num2; struct b *arrayOfB; }; > now: > I put struct a into Shared Memory: > shmid = shmget(IPC_PRIVATE, sizeof(struct a) + sizeof(struct b) * > size, 0666); Don't you also need IPC_CREATE to creates the shared memory area? > and atach it in two process: > ptr = shmat(shmid, 0, 0); > my question is: how can tell arrayOfB to point over the shared memory? Use ptr->arrayOfB = ( struct B * ) ( ( char * ) a + sizeof( struct a ) ); But your approach is a bit dangerous since there are some potential lignment issues (is a pointer pointing directly after 'struct a' suitable aligned to point to a 'struct b'?) that could get in the way. So I would recommend to create two shared memory areas, one for 'struc a' and one for the arrays of 'struct b'. Create shared memory with shmid1 = shmget( IPC_PRIVATE, sizeof( struct a ), IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ); shmid2 = shmget( IPC_PRIVATE, size * sizeof( struct b ), IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ); and then do struct a * ptr = shmat( shmid1, NULL, 0 ); ptr->arrayOfB = shmat( shmid2, NULL, 0 ); Regards, Jens -- \ Jens Thoms Toerring ___ jt(a)toerring.de \__________________________ http://toerring.de
From: Phil on 3 Jul 2008 19:39 hugo.arregui(a)gmail.com wrote: > Hi! > > I have two struts like that: > > struct { > int num; > int num2; > struct b arrayOfB[SIZE]; > > } a; > > struct { > int num3; > int num4 > > } b; > > I put struct a into Shared Memory: > shmid = shmget(IPC_PRIVATE, sizeof(struct b), 0666) > > and atach it in two process: > ptr = shmat(shmid, 0, 0); > > This works fine, but now i must delete the constant SIZE: > > I will obtain the SIZE in runtime, before execute the shmget function. You have two basic choices: Either declare "struct b arrayOfB[min]" (where min is maybe 1) and then allocate enough space for all the elements, as other posters have suggested. This is probably the simplest method. Or, implement some sort of allocator to share out blocks of memory in the shared region, and then store offsets in place of pointers. i.e. typedef intptr_t offset_t; void* get_ptr(offset_t offset) { return start_of_shmem + offset; } offset_t allocate(size_t sz) ..... void deallocate(offset_t o) ..... struct a { .... offset_t ofs_to_b; }; struct a A; A.ofs_to_b = allocate(SIZE * sizeof(b)); etc. etc. This gives you the full flexibility that you would get from pointers but with some complexity, as you can see. Note that if you store pointers in the shared memory your program will probably work perfectly. For several weeks. But then it will break, as soon as you demonstrate it to your boss, because the shared memory will get different addresses in the different processes. Phil.
From: David Schwartz on 3 Jul 2008 23:14
On Jul 3, 11:53 am, "hugo.arre...(a)gmail.com" <hugo.arre...(a)gmail.com> wrote: > but doesn't work. in another way i read about the shmat parametrs, but > don't understand how (if its possible) use to solve my trouble. A pointer in or to shared memory is useless, because there is nothing useful another process can do with it. You have a few choices, but the most flexible is to use an offset from the base of the shared memory area instead of a pointer. DS |