AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

Ein Thema von Zacherl · begonnen am 16. Mär 2015 · letzter Beitrag vom 20. Mär 2015
Antwort Antwort
Seite 1 von 3  1 23   
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#1

TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

  Alt 16. Mär 2015, 13:43
Delphi-Version: XE7
Hallo zusammen,

ich habe zwei Threads die beide auf gemeinsame Felder zugreifen. Der eine Thread kann jeweils nur schreiben, der andere nur lesen. Muss ich nun alle schreibenden Zugriffe z.b. per TInterlocked.Exchange absichern oder ist das bei nur lesendem Zugriff des einen Threads nicht nötig?

Kann es überhaupt passieren, dass die CPU Datentypen wie Byte, Word, DWord nicht atomar schreibt?

Viele Grüße
Zacherl
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.183 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

  Alt 16. Mär 2015, 14:14
Diese Interlocked-Funktionen arbeiten "atomar", so daß beim Schreibzugriff kein anderer Lesen kann.

Falls die CPU es nicht absichert, daß ein anderer Thread gleichzeitig liest, während ein Anderer schreibt, dan könnte es vielleicht passieren, daß zu von den 4 Bytes eines DWORD/INT teilweises noch ein paar Bytes von dem alten wert mit ausliest.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu (16. Mär 2015 um 14:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

  Alt 16. Mär 2015, 14:32
Der Speicher wird immer in Busbreite ausgelesen/geschreiben. Einen zusammengestückelten Wert wie 2 Bytes vom alten und 2 Bytes vom neuen Wert gibt es nicht.

Wenn du also absolut schreibst (kein addieren) dann kannst du den Wert einfach dort hineinschreiben. Sobald du mehr als einen Zugriff machen musst, um das gewünschte Resultat zu erreichen, musst du den Bereich schützen.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

  Alt 16. Mär 2015, 14:42
Der Speicher wird immer in Busbreite ausgelesen/geschreiben. Einen zusammengestückelten Wert wie 2 Bytes vom alten und 2 Bytes vom neuen Wert gibt es nicht.
Gut, dann bin ich vorerst beruhigt

Wenn du also absolut schreibst (kein addieren) dann kannst du den Wert einfach dort hineinschreiben. Sobald du mehr als einen Zugriff machen musst, um das gewünschte Resultat zu erreichen, musst du den Bereich schützen.
Jap, sowas sichere ich in der Regel mit Critical Sections.

Bei zwei Threads die beide schreiben, muss ich doch theoretisch sogar auch nichts absichern, sofern der neue Wert nicht vom alten Wert abhängt oder?
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

  Alt 16. Mär 2015, 15:09
Bei zwei Threads die beide schreiben, muss ich doch theoretisch sogar auch nichts absichern, sofern der neue Wert nicht vom alten Wert abhängt oder?
Schreib dir einfach einen Thread, der immer wieder in eine "globale" Variable einen zufälligen Wert schreibt.

Schreibe einen weiteren, der aus dieser Variable liest.

Starte jetzt mehrere von beiden Threads und schau, ob da etwas knallt. Dann hat man auch einen Erfahrungswert und wird noch viel ruhiger
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.183 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

  Alt 16. Mär 2015, 15:57
In Richtung Multiplatform betrachtet ... benutzte einfach die neuen Interlocked-Funktionen aus der System-Unit.

Die aus der Windows-Unit kann man bekanntlich nicht überall benutzen.
Aus irgendeinem unerfindlichem Grunde mach der Mac die WinAPIs nicht.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
5.872 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

  Alt 16. Mär 2015, 16:41
Einen zusammengestückelten Wert wie 2 Bytes vom alten und 2 Bytes vom neuen Wert gibt es nicht.
Ausnahme wo einfaches Lesen/Schreiben auch mit "simplen" Typen wie Integer knallt ist in wenn dieser in einem packed record steckt.

Außerdem willst du eines Tages vielleicht doch mit mehreren Threads den Wert beschreiben und freust dich dann dass es direkt ohne Anlauf möglich ist. Ich würde einfach TInterLocked oder sonst was verwenden und glücklich sein.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

  Alt 16. Mär 2015, 16:46
Einen zusammengestückelten Wert wie 2 Bytes vom alten und 2 Bytes vom neuen Wert gibt es nicht.
Ausnahme wo einfaches Lesen/Schreiben auch mit "simplen" Typen wie Integer knallt ist in wenn dieser in einem packed record steckt.
Das habe ich doch auch implizit erläutert ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#9

AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

  Alt 16. Mär 2015, 18:43
Außerdem willst du eines Tages vielleicht doch mit mehreren Threads den Wert beschreiben und freust dich dann dass es direkt ohne Anlauf möglich ist. Ich würde einfach TInterLocked oder sonst was verwenden und glücklich sein.
Nene die Felder sind in normalen Klassen. Fehlt bei den Interlocked Implementationen von Delphi btw. die 16 Bit Variante oder bin ich blind?

Zu den packed records. Sowas würde also nicht funktionieren? Verstehe ich jetzt nicht ganz ..
Delphi-Quellcode:
type
  TRec = packed record
    A: Integer;
  end;

..

Rec.A := 100;
Außer des Alignments (was beim ersten Element hier in dem Beispiel natürlich egal wäre), ändert das "packed" Attribut doch eigentlich nichts an der ganzen Geschichte.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (16. Mär 2015 um 18:47 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
9.305 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: TInterlocked.Exchange bei Zugriff eines nur lesenden Threads?

  Alt 16. Mär 2015, 20:59
Zu den packed records. Sowas würde also nicht funktionieren? Verstehe ich jetzt nicht ganz ..
Delphi-Quellcode:
type
  TRec = packed record
    A: Integer;
  end;

..

Rec.A := 100;
Außer des Alignments (was beim ersten Element hier in dem Beispiel natürlich egal wäre), ändert das "packed" Attribut doch eigentlich nichts an der ganzen Geschichte.
So wohl nicht, aber das hier:

Delphi-Quellcode:
type
  TRec = packed record
    B: Byte;
    A: Integer;
  end;
führt dazu, daß A eher nicht auf einer der CPU genehmen Speichergrenze liegt und die damit zwei Zyklen zum Schreiben braucht. Zwischen diesen beiden Zyklen kann aber ein Lesezugriff (ebenfalls zwei Zyklen) erfolgen. Das hängt aber auch konkret von der verwendeten CPU ab.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf