[C++] Concurrency probleem *

Pagina: 1
Acties:

  • Baron
  • Registratie: Juli 2000
  • Laatst online: 06-05 14:07
edit:
Oeps titel vergeten. Kan iemand zo vriendelijk zijn ?

Ik ben een fout aan het zoeken in een multi-thread programma en naar mijn gevoel is het een concurrency probleem. Nu ben ik aan het experimenteren om zeker te zijn welke code juist is en welke niet.
Onderstaand code is een programmaatje met 1 button. Telkens op de button wordt geklikt wordt er een extra thread gestart. De thread laat de globale variable 'a' met 10 verhogen. De uitvoer op het debug-scherm zouden dus altijd een veelvoud van 10 moeten zijn.

C++:
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
// TreadTestDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TreadTest.h"
#include "TreadTestDlg.h"

int a=0; //NOT thread save
CRITICAL_SECTION cs;

UINT Thread1(LPVOID iDummy) {

  CString c;
  //int a=0; // thread save
  while(iDummy ==0) {
    EnterCriticalSection(&cs);
    a++;
    Sleep(20);
    a++;
    Sleep(20);
    a++;
    Sleep(20);
    a++;
    Sleep(20);
    a++;
    Sleep(20);
    a++;
    Sleep(20);
    a++;
    Sleep(20);
    a++;
    Sleep(20);
    a++;
    Sleep(20);
    a++;
    LeaveCriticalSection(&cs);
    c.Format("%d\n", a);
    TRACE(c);
    Sleep(210);
  }
  return 0;
}


BOOL CTreadTestDlg::OnInitDialog()
{
  CODE INGEKORT ...
  // TODO: Add extra initialization here
   InitializeCriticalSection(&cs);
   return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTreadTestDlg::OnButton1()
{
   CWinThread* hThread;
   x = 0;
   hThread = AfxBeginThread(Thread1, (void *)x, THREAD_PRIORITY_NORMAL, 131072);
}


Dit is de output die krijg (2x op de button geklikked). Iemand enig idee waarom die 71 en 91 er tussen staan?
10
20
30
40
50
60
71
80
91
100

[ Voor 5% gewijzigd door Baron op 01-12-2003 12:39 ]


Verwijderd

Hmz... je title is niet echt goed. En ik vind je vraag ook niet echt thuishorend hier. Het is niet echt de bedoeling dat we hier jouw source gaan debuggen. Het is denk ik verstandig als je even alles statement voor statement runt. Zie je je foutje snel genoeg ;)

  • demonite
  • Registratie: April 2000
  • Laatst online: 23-05 06:25

demonite

the way is up

dat komt omdat TRACE niet binnen de criticalsection zit.

ps: verzin eens een naam voor dit topic

  • Baron
  • Registratie: Juli 2000
  • Laatst online: 06-05 14:07
Titel: Concurrency probleem

  • Baron
  • Registratie: Juli 2000
  • Laatst online: 06-05 14:07
demonite schreef op 01 december 2003 @ 12:41:
dat komt omdat TRACE niet binnen de criticalsection zit.
Inderdaad 8)7
deze twee regels gewisseld en het is opgelost. Stom van mij.
C++:
1
2
LeaveCriticalSection(&cs); 
c.Format("%d\n", a); 

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

offtopic:
jullie zijn snellerds, stiekem het topic al oplossen voordat ik de titel kan fix0ren :P

Professionele website nodig?


  • Baron
  • Registratie: Juli 2000
  • Laatst online: 06-05 14:07
Ik heb nog vraag dat hierbij aanleunt.

Stel 'glob' is een globale variabele van Klasse CGlobal dat in verschillende theads wordt gebruikt en de klasse van 'glob' is er als volgt uit:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
class CGlobal
{
public:
  CGlobal();
private:
   int Verwerk(int par) {
     CKlasseNietThreadSave x;
     x.functie1(par);
     x.functie2();
     return x.functie3();
  };
};


Mag ik er vanuit gaan dat de functies van klasse 'CKlasseNietThreadSafe' niet thread-safe moeten zijn omdat wanneer de method 'Verwerk' wordt uitgevoerd, een nieuwe 'x' in het geheugen wordt aangemaakt?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Baron schreef op 01 december 2003 @ 13:42:
Mag ik er vanuit gaan dat de functies van klasse 'CKlasseNietThreadSafe' niet thread-safe moeten zijn omdat wanneer de method 'Verwerk' wordt uitgevoerd, een nieuwe 'x' in het geheugen wordt aangemaakt?
Je beantwoord je vraag zelf al: CKlasseNietThreadSafe wordt binnen die functie op de STACK aangemaakt en dus heeft iedere aanroep van die functie (dus ook als je recursief zou gaan en/of multithreaded) een eigen instance.

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Maar je beantwoord 'm verkeerd, want static variabelen in de class of de class methods zijn wel shared.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:32

.oisyn

Moderator Devschuur®

Demotivational Speaker

die worden niet op de stack aangemaakt, en dat is wat curry zei

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
.oisyn: Wat bedoel je met die opmerking? Die static's die ik noem worden niet op de stack aangemaakt, nee. Alleen is dat de vraag niet.

De vraag was of Thread-safety nodig was voor de functies van CKlasseNietThreadSafe. Weliswaar is er geen thread-safety nodig voor de 'this'-pointer van CKlasseNietThreadSafe (die wijst inderdaad naar separate stacks), maar de methods van CKlasseNietThreadSafe kunnen dus wel degelijk andere data gebruiken, en die data moet wel thread-safe gebruikt worden. Statics zijn één voorbeeld, globals zijn andere variabelen, en files zijn een voorbeeld van non-memory resources die ook thread-safe moeten zijn.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:32

.oisyn

Moderator Devschuur®

Demotivational Speaker

MSalters schreef op 01 december 2003 @ 22:06:
.oisyn: Wat bedoel je met die opmerking? Die static's die ik noem worden niet op de stack aangemaakt, nee. Alleen is dat de vraag niet.
je hebt kritiek op curry omdat hij volgens jou niet rekening houdt met static variabelen. Curry zegt dat variabelen die op de stack aangemaakt worden thread-safe zijn. Maar misschien ga ik er ten onrechte vanuit dat Baron over inductieve gaven beschikt en dat hij uit de opmerking van curry op kan maken dat de functies van CKlasseNietThreadSafe ook alleen niet thread-safe hoeven zijn als zij zelf ook alleen maar van variabelen gebruik makan die op de stack aangemaakt worden ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

MSalters schreef op 01 december 2003 @ 17:44:
Maar je beantwoord 'm verkeerd, want static variabelen in de class of de class methods zijn wel shared.
Statics staan niet op de stack :)

Ik zei expliciet STACK in hoofdletters, als ik 'lokale variabelen' had gezegd had je gelijk gehad :Y)

En wat betreft statics in de classmethods zelf: dan zijn die class methods niet threadsafe. Dat doet op zich niets af aan het al of niet threadsafe zijn van de omringende constructie, dat is een ander implementatieniveau. Dat het threadunsafe zijn van de members automatisch alle aanroepen in de keten threadunsafe maakt is een 2e.

Professionele website nodig?


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 19:36
Ik ben het met MSAlters eens dat je iets te snel gaat. Als je een object op de stack alloceert, betekent dat nog niet dat alle member functions die je daarop aanroept correct uitgevoerd worden; je weet namelijk niet of die achter de schermen nog static data gebruiken.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Soultaker schreef op 01 december 2003 @ 22:41:
Ik ben het met MSAlters eens dat je iets te snel gaat. Als je een object op de stack alloceert, betekent dat nog niet dat alle member functions die je daarop aanroept correct uitgevoerd worden; je weet namelijk niet of die achter de schermen nog static data gebruiken.
Zoals ik zeg: ander implementatieniveau.

Ik kan een functie schrijven die geen exceptions gooit. Dat ik daarin wellicht functies aanroep die wel exceptions gooien is mijn verantwoordelijkheid niet, maar hoor ik natuurlijk wel rekening mee te houden. De functie zelf gooit echter geen exceptions :)

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Nou ben je aan het smokkelen. Als je een functie definieert met een gegeven interface, dan ben je zelf verantwoordelijk voor de implementatie daarvan. Dan kun je niet hopen op eigenschappen van aangeroepen functies. Een throw() functie die andere throw( non-empty ) functies aanroept zal een catch( non-empty ) moeten gebruiken. Per definitie gooit een functie namelijk alle exceptions die z'n implementatie gooit minus diegene die afgevangen worden.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Ja okee we zijn allemaal aan het mierenneuken, en we hebben allemaal gelijk :)

Essentie voor Baron: zolang alle aangeroepen functies van CKlasseNietThreadSafe (constructor + 3 memberfuncties) maar threadsafe zijn (dus geen statics gebruiken) is de functie Verwerk() ook threadsafe :)

Professionele website nodig?

Pagina: 1