Toon posts:

[c] fifo programmeren

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoi ik heb een groot probleem, ik ben voor mijn stage iets aan het maken dat in 2 threads berichten buffert en uitleest. De ene leest de andere buffert.

Ik heb een file TCP.c

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
char *bericht;
    // hierin wordt het initiele bericht--> van de dss opgevangen
char *slaOpBericht;
    // Dit bericht wordt gebruikt om de daadwerkelijke data in te kopieren
int sLuister;
int aantalPlaatsenOpStack=0;
pthread_mutex_t mutex;

typedef struct
{
    char *boodschap;
    // dit bevat het daadwerkelijk data pakketje bv {01029SDI|1023}
}IPSTACK;

void *bufferTcpMessages(void *threadId)
{   
   int i=0;  
   int lengte=0;
   while(1)
   {    
      pthread_mutex_lock(&mutex);
      lengte = recv(sLuister,bericht,1000,0);
      printf("[BUFFER-IN]:while-loop --> berichtontvangen  -- %i -- ",lengte);
      if (lengte > 0)
      {
          bericht[lengte]='\0'; // toevoegen terminator aan bericht
          slaOpBericht=(char *)malloc(lengte*sizeof(char));
          strcpy(slaOpBericht,bericht);
            
          printf("-%s-[/BUFFER-IN] \n",slaOpBericht);
        
          stack[i].boodschap = (char *)malloc(strlen(slaOpBericht)*sizeof(char));       
          stack[i].boodschap = slaOpBericht;        
          aantalPlaatsenOpStack++;
          printf("aantalplaatsenopstack -- buffer - %i\n",aantalPlaatsenOpStack);
          i++;
      }     
      pthread_mutex_unlock(&mutex);
      sleep(1);
   }
}

void *haalTcpMessageOp(void *threadId)
{
   char *bericht;
   int i,j;
    
   while(1)
   {
      pthread_mutex_lock(&mutex);
      printf("[VERWERK]haalberichtuitbuffer -->");
      for(i=0;i<aantalPlaatsenOpStack;i++)
      {
         bericht = (char *) malloc(strlen(stack[i].boodschap)*sizeof(char));
         bericht = stack[i].boodschap;
         printf("verwerkt bericht %s [/VERWERK]\n",bericht);
         printf("aantalplaatsenopstack -- haalop - %i\n",aantalPlaatsenOpStack);
         pthread_mutex_unlock(&mutex);
         sleep(2);
      }
   }
}


Dit gaat mis maar waarom, wat doe ik fout ik weet niet meer hoe het anders moet.. ben echt desperate want ik ben er al 2 maanden mee bezig

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:44

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op maandag 20 december 2004 @ 10:47:
Dit gaat mis maar waarom, wat doe ik fout ik weet niet meer hoe het anders moet.. ben echt desperate want ik ben er al 2 maanden mee bezig
Wat gaat er mis? Krijg je een foutmelding? Je bent uiteraard al door je code heen gaan stappen?

Ik heb eerlijk gezegd weinig zin om je code door te spitten totdat ik een eventuele fout zie ;)

[ Voor 13% gewijzigd door Creepy op 20-12-2004 10:49 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
nou hij compileert goed, hij buffert ook goed alleen het verwerken gaat fout. ik wil zeg maar de bovenste waarde Stack[0] telkens uitlezen en verwerken. Dan moet de array een plek omhoog geschoven worden en aantalPlaatsenOpStack moet gedecrement worden dit zou in een functie verwerkbericht moeten komen. Die op regel 56 zou moeten komen.

Ik d8 aanzoiets

code:
1
2
3
4
5
for(i=0;i<aantalplaatsenopstack-1;i++)
{
   stack[i].boodschap = stack[i+1].boodschap;
}
aantalplaatsenopstack--


maar dit werkt niet, ik weet ook ff echt niet meer hoe ik dit moet regelen

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 16:21

leuk_he

1. Controleer de kabel!

Laat eens raden wat er mis gaat: hij leest niets?

recv staat staat in de mutex lock en blokkeerd(alle) threaths totdat er daadwekrlijk iets te lezen is.

deze 2 regels omwissellen lijkt mij zo.
pthread_mutex_lock(&mutex);
lengte = recv(sLuister,bericht,1000,0);

/edit: fout geraden.

[ Voor 7% gewijzigd door leuk_he op 20-12-2004 10:56 ]

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Verwijderd

Topicstarter
hij moet dus die stack eentje omhoog schuiven na een verwerkt bericht en dit krijg ik niet voor elkaar

Ik hoop dat iemand hier ene geniaal idee heeft

[ Voor 20% gewijzigd door Verwijderd op 20-12-2004 11:00 ]


  • Rowwan
  • Registratie: November 2000
  • Laatst online: 21:42
Als je de boodschap (=string) wil copieren zul je strcpy of memcopy moeten gebruiken...

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:44

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op maandag 20 december 2004 @ 10:53:
nou hij compileert goed, hij buffert ook goed alleen het verwerken gaat fout. ik wil zeg maar de bovenste waarde Stack[0] telkens uitlezen en verwerken. Dan moet de array een plek omhoog geschoven worden en aantalPlaatsenOpStack moet gedecrement worden dit zou in een functie verwerkbericht moeten komen. Die op regel 56 zou moeten komen.

Ik d8 aanzoiets

code:
1
2
3
4
5
for(i=0;i<aantalplaatsenopstack-1;i++)
{
   stack[i].boodschap = stack[i+1].boodschap;
}
aantalplaatsenopstack--


maar dit werkt niet, ik weet ook ff echt niet meer hoe ik dit moet regelen
Misschien dat je al het opgemerkt dat we met een melding als "het werkt niet" we erg weinig kunnen.

Wat ik volgens mij mis in je code is de initializatie van je mutex?

Om te voorkomen dat je die stack steeds moet opschuiven zou je ook een begin en een eind positie kunnen aangeven. Deze hoog je steeds op. Zodra de laatste positie van de array is gebruikt spring je weer terug naar de eerste positie. Zodra je iets in de array zet hoog je "eind" 1 op. Een thread kijkt bij begin, hoogt begin 1 op, en gaat aan het verwerken.

[ Voor 18% gewijzigd door Creepy op 20-12-2004 11:03 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
damn als dat het is flip ik uit, ik ga het meteen proberen.

  • barber
  • Registratie: Oktober 2001
  • Niet online
Is het probleem niet dat in je functie haalTcpMessageOp je unlock mutex call in je for loop staat.

Verwijderd

Topicstarter
sorry das een typo, die staat buiten de for maar in de while(1)

Verwijderd

Topicstarter
zo het probleem nu is dat hij de hele tijd het eerste bericht wat er ingeschreven is verwertk. Hij verwerkt de hele tijd hetzelfde bericht terwijl dat de eerste keer al overschreven moet zijn

  • miw
  • Registratie: November 2002
  • Laatst online: 23-02 13:02

miw

Je copieert alleen pointers, niet de berichten. Is hierboven al gezegd: strncpy of memcpy gebruiken!

Verwijderd

Topicstarter
_#_")$#_#$)_#)""

Dit is te erg, zal ik eens zeggen waar het mis gaat

r34 en r36

Ik voeg telkens op de I-de plek op de Stack iets toe, ipv van op aantalPlaatsenOpStack :S:S:S:S hij schrijft alle waardes dus mooi serieel onafhankelijk van wat al verwerkt is *dom dom dom* hier ben ik dus 2 weken mee bezig geweest 8)7 8)7

ps: ik gebruik nu idd strcpy en het werkt gewoon

[ Voor 11% gewijzigd door Verwijderd op 20-12-2004 12:04 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

je mutex code klopt ook niet helemaal...

Verwijderd

Topicstarter
niet?? wat is hier dan fout aan? Hij doet het nu nog niet helemaal goed sommige codes verwerkt ie dubbel

Verwijderd

Topicstarter
Heel gek, ik heb er even over na zitten denken en ik moet het For statement van regel 52

for(i=0;i<aantalPlaatsenOpStack;i++)

wijzigen in

While (aantalPlaatsenOpStack > 0 )
{

}

maar ik krijg nu een segmentation fault als ik dit doe, hier snap ik dus echt nix van.... weet iemand hoe dit zit

  • Commander Koen
  • Registratie: Juni 2003
  • Laatst online: 26-06-2025
Gewoon een opmerking:
Je werkt met een stack maar waarom heb je geen functies geschreven voor push pop en misschien peek als dat nodig is?

En ik zou zoals creepy met een begin en eind pointer werken. Zelf vindt ik het overigens makkelijker een stack als een gelinkte lijst te implementeren. Maar ik weet niet of die array een vereiste is?

Verlaag je aantalPlaatsenOpStack met 1 voordat je de while lus in gaat?
Je array loopt van 0 tot aantalPlatsenOpStack - 1

Verwijderd

Topicstarter
Ik heb het probleem al opgelost hij loopt nu feiloos ::D:D weer wat foutjes met ene variabele :D maar nu doet hij het perfect gelukkig, bedankt allemaal voor jullie hulp!!!

ps: ik snap dat ik pointers kan maken naar het begin en het einde van de stack om toe te voegen en uit te lezen. Alleen ik ben geen [c]-goerroe dus voor mij is het nog redelijk lastig. Ik programmeer altijd in java / delphi maar bijna nooit in c. Vandaar

[ Voor 43% gewijzigd door Verwijderd op 20-12-2004 13:02 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Juist als je in java programmeert, dan weet je toch dat je een stack niet implementeert door een hele array te verschuiven elke keer? Als je perse een platte array wilt gebruiken, maak er dan een 'circular buffer' van, dat is ook in hardware een redelijk vaak voorkomende oplossing. Je hebt dus een vaste grootte array (niets met new of malloc, werkt simpel) en je houdt een begin en eind index bij. Verder heb je een increment en decrement functie/macro die bij bv dec(0) naar 'max' gaat. Iets met modulo of bit clear ops dus.

Oh die mutex, ja die in die while loop maar dat was een foutje las ik net... Verder heb ik het idee dat je iets te lang locked, in ieder geval moet je niet voor die receive je buffer locken. Die receive kan blocken, en dan hou je heel lang je buffer gelocked. Je client app kan dan geen gebufferde packets ophalen, totdat er door de overkant weer eentje gestuurd wordt. Dat is vreemd, doe die lock dus na de receive. Je moet zo kort mogelijk locken altijd.Evenals dat je bv een bericht moet ophalen, de lock vrijgeven, en het dan pas verwerken. Niet gewoon verwerken in je lock.

[ Voor 37% gewijzigd door Zoijar op 20-12-2004 13:22 ]


Verwijderd

Niemand zag het tot dusver, maar je procedures zijn stiekum functies. Ze geven namelijk een ongetypeerde en ongeinitialiseerde pointer terug (void *). Daarnaast gebruik je geen "return" aan het einde. Door de combo van deze twee zaken geeft je compiler hopelijk een paar waarschuwingen ;).

Als je je procedures Delphi-stijl wilt bouwen gebruik je proto's als
C:
1
void bufferTcpMessages(void *threadId)


void is niets
void * is een ongetypeerde pointer

  • Commander Koen
  • Registratie: Juni 2003
  • Laatst online: 26-06-2025
Een stack is overigens geen fifo maar een lifo.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Wat een rommelige code zeg. Er klopt helemaal niets van de logica in je programma (invarianten, post-/precondities?) of van de thread safety (ok, je hebt overal een grote mutex omheen gezet, maar heb je er bij nagedacht?).

De standaardimplementatie van dit systeem (wat meestal producer-consumer) werkt zoals Zoijar hem beschrijft en daarbij wordt er bovendien gebruik gemaakt van een semafoor in plaats van een mutex (wat een binaire semafoor is). Daarmee zorg je ervoor dat geen van beide threads de buffer overschrijdt.

Uitgebreide uitleg van het standaardprobleem met voorbeeldcode kun je onder andere hier vinden: The Producer/Consumer (or Bounded-Buffer) Problem
Maar door te zoeken op producer-consumer problem (eventueel in combinatie met finite/bounded buffer ofzo) is nog veel meer te vinden.

[ Voor 4% gewijzigd door Soultaker op 20-12-2004 14:57 ]


Verwijderd

Topicstarter
zeg sorry dat jij de code rommelig vind maar het gaat niet alleen voor het overschrijden van de buffer, maar ook om het dubbel lezen van waardes tijdens het resorteren van de array. Mij gaat het niet om de netheid maar om de functionaliteit

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Je hoeft je niet tegen mij te verontschuldigen; ik heb geen last van je code. (Hoop ik :P) Ik hoop dat je mijn kritiek ook niet ziet als 'afzeiken' want dat is absoluut de bedoeling niet.

Ik wil alleen maar aangeven dat je in die twee maanden beter het eerste hoofdstuk uit een willekeurig boek over concurrency of interproces-communication had kunnen doorlezen, dan had je de standaardoplossing kunnen toepassen en de garantie gehad dat die correct was. Bovendien had je dan wat geleerd over concurrency.

Ik weet niet hoe je uiteindelijke code er uit ziet, maar als hij een beetje lijkt op de code in de topic start dan zitten er nog een heleboel bugs in. Dan kun je wel zeggen dat het niet gaat om de netheid, maar als er fouten in je code zit is netheid en het gebruik van standaardalgoritmen toch echt heel wat fijner dan rommelige code die niemand (zelfs jij zelf niet) doorgrond.

Verwijderd

Topicstarter
Ik heb een blok parallel programeren gehad op mijn opleiding afgesloten met een 8 :D maar goed het enige wat ik kan zeggen is dat inderdaad bij het lezen van een bericht de lock onder het lezen moet staan ipv erboven.

Hij zou beter op regel 31 kunnen staan. Bij de andere functie kan hij echt nergens anders staan ivb met kritische variabelen.

Invarianten doe ik sinds de tu al niet meer aan ;)

Voor de rest zitten er programmeertechnisch niet zo heel veel bugs meer in. pre en post condities voeg ik later toe. En de code mag iets netter qua layout. (commentaar heb ik hier weg gelaten voor het overzicht)

[ Voor 6% gewijzigd door Verwijderd op 20-12-2004 15:33 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Verwijderd schreef op maandag 20 december 2004 @ 15:29:
Ik heb een blok parallel programeren gehad op mijn opleiding afgesloten met een 8 :D
Ja, het nivo op Nederlandse universiteiten is soms echt om te huilen; ik weet er alles van.
pre en post condities voeg ik later toe. En de code mag iets netter qua layout. (commentaar heb ik hier weg gelaten voor het overzicht)
Als je pas nadat je code klaar is over pre- en postcondities gaat nadenken heeft het waarschijnlijk niet zo veel zin meer, behalve als vorm van documentatie. Als je er in het begin over nagedacht had, zou het je een hoop werk hebben kunnen schelen. Je hoeft ze van mij betreft niet eens op te schrijven, maar denk er wel over na! (Hetzelfde geldt voor invarianten, wat eigenlijk van hetzelfde laken een pak is.)
Voor de rest zitten er programmeertechnisch niet zo heel veel bugs meer in.
En heb je al nagedacht dat je nu 'berichten' verstuurt, zonder enige vorm van delimiters, door een stream socket? Wat gebeurt er als de verzender (die waarschijnlijk standaard Nagle's algorithm gebruikt) besluit verschillende berichten achter elkaar te plakken en te verzenden? Wat gebeurt er als jouw TCP stack dat locaal doet, omdat je programma op de mutex staat te wachten? Wat gebeurt er als een bericht groter is dan de MTU (en de MTU is kleiner dan 1000, wat blijkbaar de maximale grootte van een bericht is)? Ik denk dat het puur toeval is dat de code werkt.

Verder zie ik je in de originele code op geen enkele manier garanderen dat je de ruimte op de stack niet te buiten gaat. Bovendien zie ik je allerlei dingen alloceren en niets vrijgeven. Hoe heb je dat in je uiteindelijke code opgelost?

[ Voor 5% gewijzigd door Soultaker op 20-12-2004 15:39 ]


Verwijderd

Topicstarter
Soultaker schreef op maandag 20 december 2004 @ 15:38:


En heb je al nagedacht dat je nu 'berichten' verstuurt, zonder enige vorm van delimiters, door een stream socket? Wat gebeurt er als de verzender (die waarschijnlijk standaard Nagle's algorithm gebruikt) besluit verschillende berichten achter elkaar te plakken en te verzenden? Wat gebeurt er als jouw TCP stack dat locaal doet, omdat je programma op de mutex staat te wachten? Wat gebeurt er als een bericht groter is dan de MTU (en de MTU is kleiner dan 1000, wat blijkbaar de maximale grootte van een bericht is)? Ik denk dat het puur toeval is dat de code werkt.

Verder zie ik je in de originele code op geen enkele manier garanderen dat je de ruimte op de stack niet te buiten gaat. Bovendien zie ik je allerlei dingen alloceren en niets vrijgeven. Hoe heb je dat in je uiteindelijke code opgelost?
Ik weet precies welke berichtern er binnen kunnen komen en hoe deze uitzien. Het programma dat deze berichten verstuurt is namelijk volgens een protocol door ons zelf geschreven :P.

Dit programma, haalt ze alleen op en gaat ze daarna 1 voor 1 verwerken. en dus ook kijken of het bericht wel voldoet aan het protocol. Dit gaat nog geimplementeerd worden delimiters zijn dus niet nodig. een bericht is gem 52 chars lang en maximaal 255. voor test mogelijk heden gaan we berichten tot 999 chars sturen vandaar die 1000. :D

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op maandag 20 december 2004 @ 16:10:
Dit programma, haalt ze alleen op en gaat ze daarna 1 voor 1 verwerken. en dus ook kijken of het bericht wel voldoet aan het protocol. Dit gaat nog geimplementeerd worden delimiters zijn dus niet nodig. een bericht is gem 52 chars lang en maximaal 255. voor test mogelijk heden gaan we berichten tot 999 chars sturen vandaar die 1000. :D
Yikes :) Snooping heet dat; je weet al welke test er wordt uitgevoerd, en daar pas je je code op aan (nouja, je statistiek eigenlijk, maar omdat het nu om programmeren ging :P ) Wat als ze nou met 1001 testen? :P

Het klinkt misschien als gezeur, maar soultaker heeft wel gelijk. Ik heb zelf ook al zooooo veel problemen gehad met dit soort dingen. En vooral met TCP en buffer/gefragmenteerde packets... parallel programmeren in combinatie met TCP is echt een hel. Ik probeer altijd zo snel mogelijk een atomische 'message' te krijgen. En dan daarna het liefst gebruik maken van message passing, en een monitor structuur; dus dat er altijd maar 1 iemand actief is in een bepaald stuk code. Dat is simpel te doen mbv een blocking receive. Iets meer overhead resulteert in veel makkelijker onderhoudbare code, en bovendien bug vrije code. Als je steeds wat locked, dan gaat het op een gegeven moment zeker voorkomen dat je een deadlock veroorzaakt...ga die maar eens vinden :)

[ Voor 37% gewijzigd door Zoijar op 20-12-2004 17:53 ]


  • Ritch
  • Registratie: December 1999
  • Laatst online: 09:22
http://www.cs.uu.nl/docs/vakken/gdp/gp.ps
Lees hoofdstuk 3 en dan met name 3.4 daarvan es, dan moet het je helemaal duidelijk zijn :).
Pagina: 1