www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

Shared Memory shmget size dilema, lahko kdo pomaga?
Pojdi na stran 1, 2  Naslednja
 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Linux, unix razprave
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.05
Kraj: Dragomer

PrispevekObjavljeno: Čet Sep 29, 2011 9:43 pm    Naslov sporočila:  Shared Memory shmget size dilema, lahko kdo pomaga? Odgovori s citatom

O linuxu ne vem mnogo, a problem, ki je pred menoj, bi lahko rešil z 'shared memory segment-om' s katerim bi izmenjeval podatke med dvema procecoma.

O Shared Memory se prebral http://www.cs.cf.ac.uk/Dave/C/node27.html
Tudi primer je ta prikazan, in tak kot je prikazan dela. Če pa parameter, ki določa velikost 'shared memory' povečam magari samo za 1, dobim pri izvajanju
Citiram:
shmget: Invalid argument


Shared segment se zahteva z funkcijo shmget:
Koda:
int shmget(key_t key, size_t size, int shmflg);


V primeru je velikost postavljena na 27 z
Koda:
#define SHMSZ     27

(Glej primer shmclient.c)

Če definiram manjši segment, dela v redu, če definiram večji daje omenjeno diagnostiko pri izvajanju programa.

Mi lahko kdo pomaga? Potreboval bi velikost shared segmenta vsaj 50.
Dalje piše, da je velikost segmenta zaokrožena na sledeči večji mnogokratnik page-size.a
Ali lahko potemtakem sklepam, (in polnim podatke vanj) kot da je segment velik 4096 (to je velikost strani na linux-u na katerem delam) .

Se priporočam,
VS
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
LinuxFuter
Član
Član



Pridružen-a: Pon 18 Jun 2007 14:40
Prispevkov: 386
Aktiv.: 1.88
Kraj: Novo mesto

PrispevekObjavljeno: Čet Sep 29, 2011 11:07 pm    Naslov sporočila:   Odgovori s citatom

Zakaj pa hočeš nastavit "ročno" velikost skupnega pomnilnika? Jaz sem parkrat uporabil skupen pomnilnik v linuxu in vedno sem si pomagal z operatorjem sizeof() .
Na spodnjem delu kode se ustvari skupen pomnilnik v velikosti, odvisne od prvega (ne, ni napaka) argumenta podanega ob zagonu programa ter velikosti ene spremenljivke tipa int.
Koda:

   int skp_pom = shmget(1012501, atoi(argv[1])*sizeof(int), IPC_CREAT | 0600);
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.05
Kraj: Dragomer

PrispevekObjavljeno: Pet Sep 30, 2011 7:26 am    Naslov sporočila:   Odgovori s citatom

Uuu! Našel se je nekdo, ki ima izkušnje! Hvala LinuxFiter, da si se javil.

Seveda ne vstrajam, da 'ročno' nastavim velikost, enostavno sem kopiral primer, ki sem ga našel na omenjeni strani, le da mi je 27 bajtov premalo, 100 bi bilo primerneje.
Seveda bom probal definiratu skupni pomnilnik po tvojem receptu, in upam, da bo šlo, če ne, se bom spet oglasil.

Nikjer nisem našel pojasnil, kaj pomeni tisti | 0600 v tretjem parametru. Vendar če bo delalo, kot praviš, ne bom brkljal v tej smeri.

Hvala!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.05
Kraj: Dragomer

PrispevekObjavljeno: Pet Sep 30, 2011 8:30 am    Naslov sporočila:   Odgovori s citatom

Uh, ni šlo.

Poizkusil sem z
Koda:
shmid = shmget(1012501, atoi(argv[1])*sizeof(int), IPC_CREAT | 0600

in sem dobil (jasno!) kup formalnih napak, nedefiniran argv in int. potem sem poizkusil z
Koda:
    if ((shmid = shmget(key, sizeof(niz), IPC_CREAT | 0666)) < 0)

kjer je niz definiran kot char niz[27] torej bi moral biti size 27
dobim:
Citiram:
beagleboard:~$ ./s4.exe
We enter program.
Segment is created.
Segment attached.
To se izvaja v bg samo na 8 sekund.
Data put into shared segment.
stevec = 778333813

in program zabluzi, se je zazankal, ne dela, stevec bi moral začeti z nič,
Zanimivo pa, če definiram char niz[40] pa dobim po enakem klicu shmget
Citiram:
beagleboard:~$ ./s4.exe
We enter program.
shmget: Invalid argument
beagleboard:~$


Kakšna ideja?
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.97
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Pet Sep 30, 2011 3:08 pm    Naslov sporočila:   Odgovori s citatom

vilko, a lahko prilepiš cel program, takole po koščkih je težko ugotovit, kaj je narobe.

LP!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.05
Kraj: Dragomer

PrispevekObjavljeno: Pet Sep 30, 2011 7:05 pm    Naslov sporočila:   Odgovori s citatom

Prav rad!

Program dela, kot predvideno če je drugi parameter shmget = 27 = SHMSZ kot je definirano v glavi programa, če parameter povečam, dobim napako pri izvajanju programa.

Sicer pa sem kopiral primer iz
http://www.cs.cf.ac.uk/Dave/C/node27.html (tam je size = 27!)
( no malo sem spremenil a nič v zvezi z shmget. Med tem ko primer iz omenjene strani samo enkrat napolni shm z vsebino, moj program to dela periodično. In tudi dela, če je SHMSZ = 27, če je večji pa ne.)

Tudi nimam pojma, kaj pomeni dodatek k tretjemu parametru funkcije shmget --
| 0666




Hvala za pozornosti.


Koda:
//  shm_mserver1.c
//  Učim se shared memory
//  Program naj teče v backgroundu in naj vsakih nekaj sekund
//      nekaj napiše v shared memory, in to dokumnetira na konzolo
//  To dela v neskončno, dokler process ne ubijemo

#include <stdio.h>
#include <stdlib.h>   // for itoa() call
#include <time.h>
#include <string.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
 
#define SHMSZ     27  // size of shared memory (zakaj ne dela na 28 in več???)

int main()
{
long sekunde =0;
int stevec = 0;
char niz[50];
char nizd[12];

  char c;
    int shmid;
    key_t key;
    char *shm, *s;
    printf ("We enter program.\n");
    /*
     * We'll name our shared memory segment
     * "5678".  // integer
     */
    key = 5678;
   
    /*
     * Create the segment.
   
    int shmget(key_t key, size_t size, int shmflg); 
   
    shmget() returns the identifier of the shared memory segment associated with the value of the argument key.
    A new shared memory segment, with size equal to the value of size rounded up to a multiple of PAGE_SIZE,
         is created if key has the value IPC_PRIVATE or key isn't IPC_PRIVATE, no shared memory segment corresponding to key exists,
        and IPC_CREAT is specified in shmflg.
      The value shmflg is composed of:
      IPC_EXCL used with IPC_CREAT to ensure failure if the segment already exists.   
     */
    if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0)
   {
        perror("shmget");
        return(1);
    }
    printf ("Segment is created.\n");
    /*
     * Now we attach the segment to our data space.
   
       void *shmat(int shmid, const void *shmaddr, int shmflg);
        
       shmat() attaches the shared memory segment identified by shmid to the address space of the calling process.
        The attaching address is specified by shmaddr with one of the following criteria:
               If shmaddr is NULL, the system chooses a suitable (unused) address at which to attach the segment.
        If SHM_RDONLY is specified in shmflg, the segment is attached for reading
       and the process must have read permission for the segment.
       Otherwise the segment is attached for read and write and
       the process must have read and write permission for the segment.
       There is no notion of a write-only shared memory segment.
      
       shm pointer dobi naslov                                  */   
      
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        return(1);
    }
    printf ("Segment attached.\n");
   
while (1)  // glavna programska zanka se odvija v neskončnost
   {
   // ta del programa se odvija stalno,
   // ................................
   // in stalno nadziramo pretečeni čas:
   time_t seconds;
   seconds = time (NULL);
   if (seconds > sekunde )   // če je pretečeni čas (recimo 10 sekund) potekel
      { 
      sekunde = seconds + 8;  // ponastavimo čas za sledečo periodo
      // in ta del programa se bo izvajal samo periodično
      
      strcpy (niz,"To se izvaja v bg samo na 8 sekund.\n");
      printf (niz);
      
         /*
      * Now put some things into the memory for the
      * other process to read.
      */
      s = shm;  // prenesemo naslov v character pointer s
      
      sprintf(niz,"stevec = %d\n", stevec);
        strcpy ( s, niz);       
      
      // for (c = 'a'; c <= 'z'; c++)  *s++ = c;  // v zanki prenesemo vse znake od 'a' to 'z'
      /* če koristim več kot 27 znakov, (če dvakrat napolnim segmetn) se zafuži time interval
         ne dela več periodično, temvče stalno
        for (c = 'a'; c <= 'z'; c++)  *s++ = c;  // v zanki prenesemo vse znake od 'a' to 'z'
      */      
        //*s = 0;  // in zaključimo z ničlo

      printf ("Data put into shared segment.\n");      
   //   sprintf (niz,  "Stevec je %d\n",stevec) ;   
   //   strcpy (shm ,niz) ;
        s = shm;
      strcpy (niz, s);
      printf ("%s\n", niz);

      stevec++;     
      }   // end of if
    }   // end of while
 return 0;
 }


Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
LinuxFuter
Član
Član



Pridružen-a: Pon 18 Jun 2007 14:40
Prispevkov: 386
Aktiv.: 1.88
Kraj: Novo mesto

PrispevekObjavljeno: Sob Okt 01, 2011 1:42 pm    Naslov sporočila:   Odgovori s citatom

Sicer ne bo reštiev za tvoj problem, lahko pa namesto skupnega pomnilnika uporabiš začasne datoteke, ki se jih shranjuje v /dev/shm/ (vse skupaj se še vedno shranjuje v pomnilnik), ter nato podatke med aplikacijami/procesi/itd prenašaš s pomočjo datotek Mr. Green (za urejanje dostopa, števece, itd pa uporabiš semafor ali pa monitor, če seveda veš kaj imam v mislih).
http://www.cyberciti.biz/tips/what-is-devshm-and-its-practical-usage.html
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.05
Kraj: Dragomer

PrispevekObjavljeno: Sob Okt 01, 2011 3:21 pm    Naslov sporočila:   Odgovori s citatom

LinuxFuter je napisal/a:
Sicer ne bo reštiev za tvoj problem, lahko pa namesto skupnega pomnilnika uporabiš začasne datoteke, ki se jih shranjuje v /dev/shm/ (vse skupaj se še vedno shranjuje v pomnilnik), ter nato podatke med aplikacijami/procesi/itd prenašaš s pomočjo datotek Mr. Green (za urejanje dostopa, števece, itd pa uporabiš semafor ali pa monitor, če seveda veš kaj imam v mislih).
http://www.cyberciti.biz/tips/what-is-devshm-and-its-practical-usage.html


Hmmm, seveda to potegne v paket tudi novo študiranje vsega, jaz pa sem počasen pri sprejemanju vsega novega. Vsekakor bom pogledal, hvala za link.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.97
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Ned Okt 02, 2011 7:04 pm    Naslov sporočila:   Odgovori s citatom

vilko: nisem se imel časa poglabljati v tvoj program, da bi videl, kaj bi lahko bilo narobe.

Je pa verjetno problem nekje na tvoji strani, ker meni ta program normalno dela - vsakih osem sekund izpiše stevec = 0, (z naraščajočo številko) ...

LP!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.05
Kraj: Dragomer

PrispevekObjavljeno: Ned Okt 02, 2011 9:03 pm    Naslov sporočila:   Odgovori s citatom

chaos je napisal/a:
vilko: nisem se imel časa poglabljati v tvoj program, da bi videl, kaj bi lahko bilo narobe.
Je pa verjetno problem nekje na tvoji strani, ker meni ta program normalno dela - vsakih osem sekund izpiše stevec = 0, (z naraščajočo številko) ...
LP!


Ali si kaj eksperimentiral z velikostjo shared memory? Tudi meni dela če je le ta 27 ali manj.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.97
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Ned Okt 02, 2011 9:55 pm    Naslov sporočila:   Odgovori s citatom

Okej, priznam da z shm že dolgo nisem delal, tako da sem malo pozabil, kako to deluje. Na linuxu se bolj uporablja (no, vsaj jaz to uporabljam) mmap.

Sem pa zdaj malo prečekiral, kaj je s tem - problem je v tem, da je potrebno shared memory segment po uporabi obvezno pobrisati.

Takole gre: ko enkrat alociraš shm, in če tvoj program ne pobriše segmenta, ostane shm alociran. To lahko preveriš tako, da v konzoli poženeš program ipcs, ki bo izpisal vse shared memory segmente.

Torej če shm z istim ključem že obstaja, ga sicer lahko še enkrat uporabiš, če spet zahtevaš isto velikost. Kakor boš pa v klicu shmget zahteval drugačno velikost, pa ne bo delalo.

Torej:
1. naprej poskusi pognati program z isto velikostjo segmenta. Moralo bi delati.
2. v programu spremeni ključ (key) IN velikost segmenta. Moralo bi delati.
3. pusti ključ takšen kot v 2., in povečaj velikost. Ne bi smelo delati.
4. z ukazom "ipcs" preveri, če res takšen segment obstaja.
5. z ukazom "ipcrm shm shm_id", kjer je shm_id številka shm segmenta, pobriši ta segment.
6. ponovi korak 3. Sedaj bi moralo delati.

Če dajo zgornji koraki takšne rezultate, kot sem napisal, je problem, kot sem opisal na vrhu. Torej moraš samo poskrbeti, da v programu v vseh primerih pobrišeš segment, ki ga uporabljaš (v vseh možnih izhodih iz programa). Tako pobrišeš:
Koda:

shmctl(shmid, IPC_RMID, 0);

Problem ostane samo, če program zablokira, tedaj bo segment ostal rezerviran in ga moraš pobrisati v konzoli. Oz. verjetno dela, če dodaš nekaj takšnega na začetek programa:
Koda:

shmid = shmget(key, 0, IPC_CREAT | 0666);
shmctl(shmid, IPC_RMID, 0);

Ta del kode bi moral segment, če že obstaja, priključiti ne glede na velikost, in z drugim ukazom ga nato pobrišeš. Potem ga pa normalno spet alociraš kot imaš sedaj v programu.

Upam, da sem razumljivo napisal Smile

LP!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.05
Kraj: Dragomer

PrispevekObjavljeno: Ned Okt 02, 2011 10:03 pm    Naslov sporočila:   Odgovori s citatom

Hvala za izčrpno pojasnilo, zelo si se potrudil, cenim.

Toda meni je 27 bajtov premalo, in sploh ne morem alocirati segmenta potrebne velikosti niti na samem začetku.
Morda bi šlo z več segmenti, a to bi zapletlo programiranje.
Segmenta nisem nameraval brisati, temveč stalno uporabljati - pisati v enem programu, in ko drugi program ugotovi spremembo, da vsebina segmenta ni ista, tedaj bi drugi program prebral in obravnaval novo vsebino segmenta.

Sem pa nad to temo že malo obupal, je pač pretrd oreh zame in bom problem rešil verjetno v enem samem programu. Bo malo bolj zapleteno, ampak bo. Tako shared segmenta niti potreboval ne bom.

Hvala za trud.
Lep pozdrav
vs
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.97
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Ned Okt 02, 2011 10:18 pm    Naslov sporočila:   Odgovori s citatom

Daj za vsak slučaj v konzoli napiši ukaz ipcs, in preveri, da slučajno segmenti že (še kar) obstajajo.

LP!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.05
Kraj: Dragomer

PrispevekObjavljeno: Ned Okt 02, 2011 10:26 pm    Naslov sporočila:   Odgovori s citatom

chaos je napisal/a:
Daj za vsak slučaj v konzoli napiši ukaz ipcs, in preveri, da slučajno segmenti že (še kar) obstajajo.
LP!


Ha, pa res obstaja, a ga ne morem brisati, ali naj da 5678 (id) kako v aprostofe ali kaj?
Preveril sem X162E == dec 5678



Citiram:
beagleboard:~$ ipcs

------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x0000162e 0 vilko 666 27 0

------ Semaphore Arrays --------
key semid owner perms nsems

------ Message Queues --------
key msqid owner perms used-bytes messages

beagleboard:~$ ipcrm shm 5678
cannot remove id 5678 (Invalid argument)
beagleboard:~$


Ali se segment ne briše avtomatsko, ko ugasneš job?
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.97
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Ned Okt 02, 2011 10:28 pm    Naslov sporočila:   Odgovori s citatom

Uporabi shmid, ne key - v tvojem primeru 0.

LP!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Linux, unix razprave Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Pojdi na stran 1, 2  Naslednja
Stran 1 od 2

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 66 dni


Powered by phpBB © 2001, 2005 phpBB Group