Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Zeus

Frischling

  • »Zeus« ist der Autor dieses Themas

Beiträge: 83

Beruf: Schule

  • Private Nachricht senden

1

09.09.2010, 12:23

CriticalSection vs. Mutex

Hey Leute,

wie der Titel erahnen lässt geht die Frage um den vergleich der threadblockierenden Techniken und deren Einsatz.

Da ich im Moment zu Testzwecken eine kleine ThreadSave-Bibliothek zusammenschreibe, und mit den oben gennanten Techniken herumspiele wollte ich zum einen Wissen worin sich eine CriticalSection von einem Mutex unterscheidet ? Ich habe mal gelesen das Mutex zwischen mehreren Prozessen geteilt werden kann. Ist das der einzige Unterschied ? Wenn ja kann man sich in einem Projekt das nur ein Prozess ist den Einsatz von Mutex ja sparen da sie afaik langsamer sind als CS.

Wenn ich Mutex und CS kapsel, in wie weit bleibt ihre ursprüngliche Funktion (z.B. bei einem Mutex zwischen Prozessen geteilt zu werden) dann noch erhalten ?

mfg Zeus
Ich würde die Welt gerne verbessern, doch Gott gibt mir den Quellcode nicht!

Sprachen: C,C++/CLI,C#,ASM,PHP,Java(-script) ... fürn Anfang auch genug ...

Mein letztes Projekt:

http://www.youtube.com/watch?v=vU14ewcVaXU

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

09.09.2010, 13:14

Den Hauptunterschied hast du ja bereits genannt: CriticalSections sind nicht Prozessübergreifend nutzbar (im Gegensatz zu Mutex-Objekten), deshalb können CriticalSections einen effizienteren Mechanismus anbieten.

Die API unterscheidet sich aber bei der Verwendung. CriticalSections werden übernommen mit EnterCriticalSection oder TryEnterCriticalSection, wobei bei keiner der beiden Funktionen ein Timeout angegeben werden kann (EnterCriticalSection wartet unendlich lang, TryEnterCriticalSection kommt sofort zurück), bei Mutex-Objekten ist das möglich (WaitForSingleObject).

Ausserdem gibt es für CriticalSections keine Möglichkeiten festzustellen ob ein CriticalSection-Objekt den Status abandoned hat oder nicht.

Mehr Infos dazu:
http://msdn.microsoft.com/en-us/library/…28VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/…v=VS.85%29.aspx
@D13_Dreinig

Zeus

Frischling

  • »Zeus« ist der Autor dieses Themas

Beiträge: 83

Beruf: Schule

  • Private Nachricht senden

3

09.09.2010, 13:19

Danke, sowas hab ich gesucht :) aber seit MSDN umgestellt hat finde ich Nichts mehr ... Und C# hilft mir grad nicht weiter auch wenn MS drauf besteht das es das ist was ich such xD :P ...
Ich würde die Welt gerne verbessern, doch Gott gibt mir den Quellcode nicht!

Sprachen: C,C++/CLI,C#,ASM,PHP,Java(-script) ... fürn Anfang auch genug ...

Mein letztes Projekt:

http://www.youtube.com/watch?v=vU14ewcVaXU

MasterK

Frischling

Beiträge: 92

Wohnort: Koblenz

Beruf: Teamleiter Softwareentwicklung

  • Private Nachricht senden

4

10.09.2010, 00:45

Der begriff "Mutex" ist erst einmal ziemlich allgemein. Die unterscheidung "prozessübergreifend oder nicht" ist dort quatsch. In manchen bibliotheken ist der mutex prozess-übergreifend, in manchen nicht.

Zeus

Frischling

  • »Zeus« ist der Autor dieses Themas

Beiträge: 83

Beruf: Schule

  • Private Nachricht senden

5

10.09.2010, 00:56

Da ich nativ auf Windows aufbauen will interessieren mich die Win-API Bibliotheken am meisten ;) ... wenn du Tipps hast ... bin um alles Dankbar ... Im Moment knobel ich an einem Exception sicheren Lock ... Wenn eine Exception auftaucht ... Wird die Klasse in der sie auftaucht dann abgebaut ? Also ich kann ich einfach einen Mutex kapseln und der wird durch die Exception und das Abbauen der Threadklass mit abgebaut?
Ich würde die Welt gerne verbessern, doch Gott gibt mir den Quellcode nicht!

Sprachen: C,C++/CLI,C#,ASM,PHP,Java(-script) ... fürn Anfang auch genug ...

Mein letztes Projekt:

http://www.youtube.com/watch?v=vU14ewcVaXU

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

10.09.2010, 01:23

Im Moment knobel ich an einem Exception sicheren Lock

Die Antwort ist, wie praktisch immer in diesen Belangen, RAII:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  template<class T = CriticalSection>
  class scoped_lock
  {
  private:
    T& _obj;
    scoped_lock(const scoped_lock&);
    scoped_lock& operator =(const scoped_lock&);
  public:
    scoped_lock(T& obj) : _obj(obj) { _obj.acquire(); }
    ~scoped_lock() { _obj.release(); }
  };

  // ...

{
  scoped_lock<> lock(mutex);

  // ...

}

Zeus

Frischling

  • »Zeus« ist der Autor dieses Themas

Beiträge: 83

Beruf: Schule

  • Private Nachricht senden

7

10.09.2010, 04:30

Ja, das Beispiel habe ich hier schonmal ein einem Diskussionsthread gefunden (samt etwas mehr Listing). Allerdings bin ich daraus nicht wirklich schlau geworden. Warum Wrappe ich nochmal eine Klasse um das Ganze wenn ich last but not least nur eine Funktion aufrufe.

Mein momentaner Versuch sieht so aus. Sag mir wenn ich auf dem totalen Holzweg bin.

C-/C++-Quelltext

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
class CriticalSection : public Security::Lackable 
{
private: CRITICAL_SECTION Crit; 
private: bool mode;public: explicit CriticalSection() 
{
this->init(); 

} 
public: explicit CriticalSection(CRITICAL_SECTION &section) 
{
this->Crit = section;this->init(); 

}
public: void init() 
{ 
InitializeCriticalSection(&Crit); 
}
public: ~CriticalSection() 
{
this->unlock(); 
DeleteCriticalSection(&Crit); 
}
public: virtual void lock() 
{ 
EnterCriticalSection(&Crit);
this->mode = true; 
}
public: virtual void unlock() 
{ 
LeaveCriticalSection(&Crit);
this->mode = false; 
}
public: bool locked() 
{
return this->mode; 
} 
}; 

........ 
{ 
CriticalSection m; 
m.lock(); 
... 
} 
............ 
oder unter annahme einer weiteren Überladung 
{ 
CriticalSection m(true); 
... 
}


Den Constructor hätte ich schnell um einen weiteren Überladen sodas ein Parameter angibt ob gleich gelockt werden soll. Dann wäre das Technisch doch das gleiche ? ...
Ich würde die Welt gerne verbessern, doch Gott gibt mir den Quellcode nicht!

Sprachen: C,C++/CLI,C#,ASM,PHP,Java(-script) ... fürn Anfang auch genug ...

Mein letztes Projekt:

http://www.youtube.com/watch?v=vU14ewcVaXU

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

10.09.2010, 10:27

Den Constructor hätte ich schnell um einen weiteren Überladen sodas ein Parameter angibt ob gleich gelockt werden soll. Dann wäre das Technisch doch das gleiche ? ...

Nein, ganz und gar nicht. Ich denke du solltest dich unbedingt mal mit RAII auseinandersetzen. RAII ist die Grundlage für exception sicheren Code überhaupt.

Zu deiner CriticalSection Klasse vielleicht ein paar Fragen/Anmerkungen:
  • Ist es wirklich notwendig eine CriticalSection von Lockable abzuleiten?
  • Was hat Lockable mit Security zu tun?
  • Warum eine init() Methode? Und wenn schon warum muss die public sein?
  • Braucht die Klasse wirklich einen Konstruktor der eine CRITICAL_SECTION übergeben bekommt? Was genau ist der Sinn davon und ist dir klar was genau dieser Konstruktor tut so wie du ihn jetzt implementiert hast?
  • Macht es Sinn eine CriticalSection zu kopieren oder ihr einen neuen Wert zuzuweisen? Wenn nein warum unterstützt deine Klasse das dann?
  • Ist der Member mode wirklich notwendig? Wenn du ihn behalten willst sollte die Methode locked() zumindest const sein.
  • explicit auf einem Default Konstruktor ist sinnlos.
  • Natürlich ist das eine Stilfrage aber ich finde es extrem unübersichtlich vor jeden Member public: bzw. private: zu schreiben.

Ich verwende normalerweise einfach sowas in der Art:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  class CriticalSection
  {
  private:
    CriticalSection(const CriticalSection&);
    CriticalSection& operator =(const CriticalSection&);

    CRITICAL_SECTION s;
  public:
    CriticalSection() { InitializeCriticalSection(&s); }
    ~CriticalSection() { DeleteCriticalSection(&s); }

    void acquire() { EnterCriticalSection(&s); }
    void release() { LeaveCriticalSection(&s); }
    bool tryacquire() { TryEnterCriticalSection(&s); }
  };

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »dot« (10.09.2010, 10:46)


Zeus

Frischling

  • »Zeus« ist der Autor dieses Themas

Beiträge: 83

Beruf: Schule

  • Private Nachricht senden

9

10.09.2010, 13:37

Jap, habe mir den Link auch schon gespeichert. Werde mich da einarbeiten. Sorry wenn ich so viele Fragen stelle nur ich fange jetzt erst mit mehreren Threads an :S

Wow ... viele Fragen. Dann mach ich mich mal an die Beantwortung ...

Lockable ist eine Basisklasse die 2 virtuelle Funktionen hat und sich von "Unique" ableitet. Auf die weise möchte ich sicher stellen das alle Mutex, Semaphore und CriticalSections in jeder Form zumindest ein lock() und unlock() anbieten und einen privaten copy-constructor und privaten zuweisungsoberator haben (letztere beiden aspecte kommen von Unique).

Ja da könnte ich drüber nachdenken sie in einen anderen Namespace zu schieben. Sie hatte vorher einen anderen Namen und hat deshalb da am besten rein gepasst.

Muss nicht, hab ich übersehn. wird privat :) Danke

Ich habe in irgend einem Tutorial mal gesehn das wenn sich mehrere "Locks" eine CS teilen das sie den gleichen Bereich schützen. Also wenn die CS identisch ist kann ich mehrere Lock-Objekte instanzieren die das gleiche schützen ... Unterliege ich da einem Fehler ?

Habe ich schon oben erklärt. Da ist noch eine andere Klasse "Unique" ... Die ist durch "Lockable" auch teil von CriticalSection.

Ich finde es an CS sehr unschön das man keine Möglichkeit hat den Status zu überprüfen. Deshalb finde ich ihn praktisch. Ja, mach ich ...

Stimm ich dir zu ... War vorher auch kein Def-Constructor
Ich würde die Welt gerne verbessern, doch Gott gibt mir den Quellcode nicht!

Sprachen: C,C++/CLI,C#,ASM,PHP,Java(-script) ... fürn Anfang auch genug ...

Mein letztes Projekt:

http://www.youtube.com/watch?v=vU14ewcVaXU

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

10

10.09.2010, 14:27

Ich habe in irgend einem Tutorial mal gesehn das wenn sich mehrere "Locks" eine CS teilen das sie den gleichen Bereich schützen. Also wenn die CS identisch ist kann ich mehrere Lock-Objekte instanzieren die das gleiche schützen ... Unterliege ich da einem Fehler ?


Wenn du das tun willst sollte deine Klasse eine Referenz auf das CRITICAL_SECTION Objekt halten. Im Moment kopierst du das Objekt nur. Somit wirken sich alle Aktionen die du auf das Objekt machst nur lokal (in der Instanz von CriticalSection) aus.
Kritischer ist, dass du das übergebene CRITICAL_SECTION Objekt, per InitializeCriticalSection, initialisierst. Sollte das vorher schon geschehen sein (und _das_ ist sehr wahrscheinlich, weil du die Idee von geteilten Synchronisations-Objekten verfolgst) dann resultiert das in einem undefinierten Verhalten.
@D13_Dreinig

Werbeanzeige