AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

TBitmap ist NICHT threadsave

Ein Thema von Kraisel · begonnen am 13. Jun 2016 · letzter Beitrag vom 18. Jun 2016
Antwort Antwort
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: TBitmap ist NICHT threadsave

  Alt 14. Jun 2016, 19:14
@Rollo62

Es gibt keine konkrete Aussage darüber, was man von TBitmap gefahrlos im Thread verwenden kann und was nicht - es hat beim Klassendesign keinen interessiert.

Zugesichert wird nur das korrekte Verhalten im MainThread.

Den Rest muss man sich durch SourceCode-Wälzen zusammensuchen. Einfaches Ausprobieren reicht da leider nicht aus, denn eine race condition macht sich meist erst dann bemerkbar, wenn man gerade nicht hinschaut (Murphys Law)
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 Kraisel
Kraisel

Registriert seit: 19. Mär 2012
Ort: Bochum-Linden
64 Beiträge
 
Delphi 12 Athens
 
#2

AW: TBitmap ist NICHT threadsave

  Alt 15. Jun 2016, 00:17
Kategorie "ganz blöd" kannte ich noch nicht, aber sofort in mein Repertoire aufgenommen.

Wenn es unbedingt parallel sein muss, geht es so:

1) MainThread: Kopie einer Bmp in ein allociertes Memory, das geht sau schnell, wenn man das Memory genau wie die Bmp organisiert.
2) SomeThread: Manipulieren des Memories, vielleicht den alten Brasenham-Algorithmus wieder aus dem Keller holen. Aber bitte an den Rändern richtig clippen. Sonst gibt es Überraschungen.
3) MainThread: Kopie des Memories zurück in die Bmp, das geht wieder schnell.

So mache ich z.B. 3D - Rotationen (ohne die 3D-Engine vom System) mit mehreren Threads gleichzeitig. Das funktioniert einwandfrei. Man muss nur schmerzfrei bleiben, bis alles läuft.

Für viele Aufgaben, die man hat, kann man ja eine eigene TcMemBmp-Class bauen. Bilder abdunkeln, aufhellen, oder sogar Linien zeichnen ist ja trivial. Benötigt man aber den gesamten Comfort des Canvas oder will rendern, sollte man wohl besser im MainThread bleiben.

Wahrscheinlich könnte man auch eine dll schreiben, die nichts anderes macht, als Bitmaps zeichnen. Aber das ist irgendwie auch "ganz blöd".
Peter Kaisler
Das einzig Komplizierte ist zu begreifen wie einfach es ist.
  Mit Zitat antworten Zitat
Benutzerbild von Kraisel
Kraisel

Registriert seit: 19. Mär 2012
Ort: Bochum-Linden
64 Beiträge
 
Delphi 12 Athens
 
#3

AW: TBitmap ist NICHT threadsave

  Alt 15. Jun 2016, 00:43
Vielleicht kann man aber folgendes machen:

1) MainThread: Bmp.map aufrufen.
2) SomeThread: Direktes Manipulieren der TBitmapData.Data.
3) MainThread: Bmp.unmap aufrufen.

Das müsste ja OK sein, solange der MainThread die Bmp nicht anrührt, bis die Threads fertig sind. Oder?
Peter Kaisler
Das einzig Komplizierte ist zu begreifen wie einfach es ist.
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#4

AW: TBitmap ist NICHT threadsave

  Alt 15. Jun 2016, 01:34
Disclaimer: Ich hab keinen Einblick wie das genau implementiert ist.

Wenn der Mainthread mit einem blanken Zeiger auf den Daten herumholzen kann, sollte das der Hilfsthread auch können. Denke aber daran, dass der Ablauf dann richtig synchronisiert werden muss.
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.
  Mit Zitat antworten Zitat
Benutzerbild von Kraisel
Kraisel

Registriert seit: 19. Mär 2012
Ort: Bochum-Linden
64 Beiträge
 
Delphi 12 Athens
 
#5

AW: TBitmap ist NICHT threadsave

  Alt 16. Jun 2016, 21:18
Abschlusserkenntnisse:

Folgende Aussagen kann ich für XE10.1 und Firemonkey bestätigen:

So, ... und wohl nur so funktioniert es mit TBitmap im Thread einwandfrei. Passt auch zu einigen vorangegangenen Kommentaren.

1) MainTread: TBitmap.Create, dann beliebig auf dem Canvas herummalen
2) MainTread: Bitmap.Map (ReadWrite)
3) SomeThreads: Beliebig "zu Fuß" in den Buffer malen und/oder lesen. (Je Zugriff natürlich mit anderen Threads, falls vorhanden, verriegeln).
4) MainTread: Warten, bis Threads fertig sind, Bitmap.Unmap, und beliebig weiterbenutzen

Ich habe noch einmal ca. 4.5 Millionen TBitmaps (jeweils Zufallgroesse 1:1 .. 1280:800) erzeugt und im threadgetriebenen Stresstest (4 TTasks) 1.2 Tera Pixel verglichen (ca. 8 Stunden).

Das einzige, was man laut meinem Stresstest im Thread machen darf, ist auf die gemapten BitmapData lesend und schreibend zugreifen.

Alles andere macht Probleme und zwar sofort bis "fast nie". Letzteres ist TBitmap.Create/Free und/oder TBitmap.Map/Unmap im Thread. Das geht nur ca. jedes 1000 mal schief und es stimmen einzelne Pixel nicht mehr. Ein später kaum zu findener Fehler.
Peter Kaisler
Das einzig Komplizierte ist zu begreifen wie einfach es ist.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.560 Beiträge
 
Delphi 12 Athens
 
#6

AW: TBitmap ist NICHT threadsave

  Alt 16. Jun 2016, 22:25
Mr. Spock würde sagen "Faszinierend". Also, mit welcher Konsequenz und Umfang Du Deine Tests hier durchziehst.

Nur ist das so ohne ein wenig Code zu sehen leider wenig transparent und daher nicht so richtig nachvollziehbar. So ein paar Codefragmente wären schon interessant, z.B. wie Du die Maping und Unmapping Sequenzen konkret umsetzt und die Threads aufsetzt.

Du brauchst ja hier auch gar nicht Deinen ganzen Test hochladen, der vollständig kompiliert, die grundlegenden Abschnitte wo Mainthread und Einzelthreads in Konkurrenz zueinander arbeiten, das würde ja schon reichen.

Und insofern im Vergleich zu sehen, was nicht geht und was geht.
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.174 Beiträge
 
Delphi 12 Athens
 
#7

AW: TBitmap ist NICHT threadsave

  Alt 18. Jun 2016, 11:56
Hallo Kraisel,

sehr interesant. Es müsste mit dem map/unmap ja besser gekapselt sein als unter VCL.

Trotzdem muss ich mich Harry anschliessen, wäre gut zu wissen was genau. Z.B. auch: Läuft das unter ios Andoid osx win64 ?


Die Probleme komen ja meist wenn man sich von Win32 wegbewegt
(Hätte nie gedacht das ich sowas mal sagen würde).

Rollo
  Mit Zitat antworten Zitat
Antwort Antwort

 
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 11:34 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz