Avatar billede rellin Nybegynder
27. oktober 2002 - 17:04 Der er 13 kommentarer og
1 løsning

Globale variable ved fork

Jeg har et standard c-program i linux der arbejder på nogle globale variable. Det fungerer som en server, der forker hver gang det modtager en forespørgsel.
Mit problem er nu, at når childprocesserne ændrer de globale variable, ændres de ikke i parentprocessen.

Hvordan får jeg gjort det sådan at de globale variable kun oprettes en gang, og ikke kopieres med i childprocesserne. Det jeg søger er altså noget lignende kommandoen "static" i java...
Avatar billede arne_v Ekspert
27. oktober 2002 - 17:22 #1
Ikke noget svar, men i Java bruger man threading ikke
forking. Og det er en vigtig forskel i denne sammenhæng.
Avatar billede arne_v Ekspert
27. oktober 2002 - 17:28 #2
Du kunne bruge shared memory.

Jeg ved ikke en meter om shared memory under Linux,
men google gav følgende link:
  http://www.acm.uiuc.edu/lug/presentations/shm/shm.html
Avatar billede rellin Nybegynder
27. oktober 2002 - 17:30 #3
Der må da være en slags "konstant" som ikke kan "kopieres" når der fork()'es.
Avatar billede rellin Nybegynder
27. oktober 2002 - 17:31 #4
Vil helst undgå shared memory
Avatar billede dittmer Nybegynder
27. oktober 2002 - 17:31 #5
Hvis du laver en fork() i C, så kopierer du hele konteksten til et nyt adresserum. Ved brug af letvægtsprocesser (aka. threads/tråde) ligger de i samme adresserum - de er en del af samme proces. Bl.a. herfor er tråde billige at oprette i forhold til processer.

Hvis du vil lave "globale variabler" for adskilte processer skal de enten ligge i shared memory (som er et systemkald), eller osse skal du lave noget f.eks. som at oprette to pipes (én læse- og én skrive-) *inden* du laver en fork(). Derefter kan du give forældreprocessen besked om at du vil ændre en global variabel.

Mvh
Søren
Avatar billede rellin Nybegynder
27. oktober 2002 - 17:39 #6
Hmm.. ja kan man ikke evt. bruge message passing til det istedetfor pipes?

Eller kan man måske angive childprocessererne skal arbejde på det samme adresserum som parentesprocesserne?
Avatar billede dittmer Nybegynder
27. oktober 2002 - 18:16 #7
Du kan godt bruge message passing - det er derfor, der står "F.eks."...

Hvis du angiver childprocesserne til at arbejde i samme adresserum som forældreprocessen, så har du problemer: Hvordan sikrer du, at dine processer kun deler globale variabler, og ikke bruger den enes program segment som temporært lager for den anden? Ved fork() er det pr. definition en kopi af dit program, der udføres i et andet adresserum. Det vil simpelthen give dig muchomange problemer hvis du kunne få to processer til at køre i samme adresserum. Hvis du virkelig ønsker det, kan du så ikke bruge threads i stedet?
Avatar billede rellin Nybegynder
27. oktober 2002 - 18:22 #8
Kan man SÅ evt. sende argumenter med fra forældre-processen til childprocesserne?

Jeg tænker f.eks. på om man kan sende en pointer med?
Avatar billede dittmer Nybegynder
27. oktober 2002 - 21:13 #9
Du kan ikke sende argumenter med i et kald til fork().

Hvis du vil give childprocessen noget at arbejde med, kan du lægge nogle værdier i variabler inden kaldet til fork(), og det første din nye proces skal gøre er at læse disse (kopierede) variabler og udføre noget i overensstemmeler hermed.

Men du kan også sende noget i en pipe/queue/shared memory. Du kan jo sende hvad som helst - og det er så op til modtageren at fortolke det modtagne på passende vis. Hvis det drejer sig om en pointer til noget shared memory, så kan du endda bruge den til noget, men hvis det er til forældreprocessens eget adresserum, vil du få en over de virtuelle fingre (dvs. ethvert operativsystem opbygget efter moderne flerproces- og flerbrugerprincipper vil gøre det).

Der findes en beslægtet version af fork(), der hedder vfork(). Den er udelukkende beregnet til at lave en proces, der enten kalder exec() (starte et andet, eksternt program) eller exit() (afslutte sin proces). Da dette sker ret hurtigt, og da processen ikke skal køre noget programkode selv, får denne childproces lov til at køre i samme adresserum. Det er imidlertid sindssygt farligt at bruge den til andet end dette, da der ikke er nogen beskyttelse på adresserummet...

Nu ved jeg ikke, hvorfor du helst vil undgå shared memory, men det er den hurtigste form for inter-proceskommunikation, der er på maskinen. Det er let at bruge, men har en begrænsning i størrelsen af den delte område (systembestemt). Eneste lille finte er at man skal huske at afskærme ressourcerne ved brug af semaforer, fillåse eller lignende.
Avatar billede dittmer Nybegynder
27. oktober 2002 - 21:19 #10
Kom lige til at tænke på: Gu' ved om man kan lave følgende (i pseudokode):

opret shared memory
opret to pipes fra og til sig selv: én læsepipe og én skrivepipe
skriv værdier til pipe
pid = fork()
hvis pid = 0 /* vi er i child-processen */
  læs fra pipe
ellers /* vi er i forældreprocessen */
  gør noget andet

Jeg ved ikke om det kan lade sig gøre, og resultatet er vel ikke anderledes end hvis forældreprocessen *efter* et kald til fork() skriver til sit nye barn gennem en pipe?
Avatar billede rellin Nybegynder
27. oktober 2002 - 22:31 #11
Jeg havde ellers regnet med at alle mine childprocesser kunne "pege" dvs. pointers ind mod den samme liste... uden shared memory men det lader til at det ikke kan lade sig gøre det kunne ellers være smart!

Men er for træt må lige tænke!
Avatar billede rellin Nybegynder
28. oktober 2002 - 13:19 #12
Okay, jeg er blevet overbevist om at bruge shared memory.
Problemet er bare, at det er en hægtet liste jeg arbejder med, hvordan får jeg lagt den ind i shared memory?
Jeg kan godt få lagt et element fra listen ind i shared memory, men hvordan lægger jeg hele listen ind? Skal jeg oprette et shared memory-segment for hvert listeelement?, og hvordan får jeg så segmenterne til at pege på hinanden?
Avatar billede rellin Nybegynder
28. oktober 2002 - 23:50 #13
Har selv løst problemet
Avatar billede dittmer Nybegynder
29. oktober 2002 - 08:19 #14
Øh... Hvad var der galt i svaret?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester