DE19957594B4 - Verfahren zum Synchronisieren von threads eines Computerprogramms - Google Patents

Verfahren zum Synchronisieren von threads eines Computerprogramms Download PDF

Info

Publication number
DE19957594B4
DE19957594B4 DE19957594A DE19957594A DE19957594B4 DE 19957594 B4 DE19957594 B4 DE 19957594B4 DE 19957594 A DE19957594 A DE 19957594A DE 19957594 A DE19957594 A DE 19957594A DE 19957594 B4 DE19957594 B4 DE 19957594B4
Authority
DE
Germany
Prior art keywords
buffer
data
read
section
threads
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
DE19957594A
Other languages
English (en)
Other versions
DE19957594A1 (de
Inventor
Hermann Lankreijer
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Canon Production Printing Germany GmbH and Co KG
Original Assignee
Oce Printing Systems GmbH and Co KG
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Oce Printing Systems GmbH and Co KG filed Critical Oce Printing Systems GmbH and Co KG
Priority to DE19957594A priority Critical patent/DE19957594B4/de
Priority to PCT/EP2000/012048 priority patent/WO2001040931A2/de
Priority to US10/148,376 priority patent/US7266825B2/en
Publication of DE19957594A1 publication Critical patent/DE19957594A1/de
Application granted granted Critical
Publication of DE19957594B4 publication Critical patent/DE19957594B4/de
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/45Exploiting coarse grain parallelism in compilation, i.e. parallelism between groups of instructions
    • G06F8/458Synchronisation, e.g. post-wait, barriers, locks

Landscapes

  • Engineering & Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Multi Processors (AREA)
  • Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
  • Memory System Of A Hierarchy Structure (AREA)

Abstract

Verfahren zum Synchronisieren von threads (PO, P1, P3) eines Computerprogramms (Co-Pr), wobei
(a) in dem in threads aufgeteilten Computerprogramm (Co-Pr) Erzeuger-threads (P1, P2), die Daten für einen anderen thread erzeugen, diese Daten jeweils in Pufferabschnitte (PA1 – PA6) flexibler Größe eines Puffers (Pu) schreiben, wobei der letzte physikalische Pufferabschnitt (PA6) nicht beschrieben wird und nach dem Beschreiben des vorletzten Pufferabschnitts (PA5) wieder am Anfang des physikalischen Puffers mit dem Schreiben begonnen wird und wobei Lese-threads (P2, P3) die erzeugten Daten aus dem Puffer (Pu) auslesen,
(b) zum Freigeben und Sperren der Schreibvorgänge und der Lesevorgänge Puffer-Dienstprogramme (S5, S7, S14) verwendet werden,
(c) während dem Zugriff eines ersten Puffer-Dienstprogrammes auf den Puffer (Pu) ein gleichzeitiger Zugriff auf den Puffer (Pu) für ein zweites Puffer-Dienstprogramm verhindert wird,
(d) die Pufferabschnitte (PA1 – PA6) von den Puffer-Dienstprogrammen (S5, S7, S14) mit jeweils einem Flag versehen werden, durch das ein...

Description

  • Die Erfindung betrifft ein Verfahren zum Synchronisieren von threads eines Computerprogramms, dessen threads parallel auf unterschiedlichen Prozessoren eines Computers ablaufen können.
  • In „Win 32 Multithreaded Programming, Aaron Cohen und Mike Woodring, O'Reilly & Associates Inc., ISBN 1-56592-296-4" ist insbesondere auf den Seiten 258 bis 269 und 301 bis 303 die Programmierung und Synchronisierung von threads erläutert.
  • Threads, die Daten für einen anderen thread erzeugen, werden als Erzeuger oder Schreiber und threads, die derartige Daten verarbeiten, als Verbraucher oder Leser bezeichnet. Um beim Aufteilen der Arbeit zwischen den einzelnen threads die Rechenleistung eines Computers mit mehreren Prozessoren optimal auszunutzen ist es notwendig, dass die einzelnen threads asynchron betrieben werden. Dies bedeutet, dass der Erzeuger-thread soviel Daten erzeugen kann, wie er wünscht, und der Lese-thread soviel Daten lesen kann, wie zur Verfügung stehen, ohne dass hierbei Rücksicht auf den anderen thread genommen werden muss. Die Daten eines Erzeuger-threads werden von diesen in Pakete (Messages) gepackt und in eine Reihe (Queue) eingereiht, aus der der Lese-thread die Pakete aufnehmen und weiterverarbeiten kann.
  • Die einzelnen threads sind mit Funktionen versehen, die warten, bis sie ein entsprechendes Paket in einer Reihe ablegen können, oder bis ein entsprechendes Paket zum Lesen angekommen ist, damit immer die korrekte Zuordnung der Daten zu den sie verarbei tenden Funktionen sichergestellt ist. Hierdurch wird der Transport der Daten synchronisiert.
  • Die Synchronisation des Datentransfers zwischen einzelnen threads kann intern oder extern ausgeführt werden. Unter einer internen Synchronisation versteht man eine Synchronisation, bei der die einzelnen Synchronisationsvorgänge von den threads ausgeführt werden, wohingegen eine externe Synchronisation mittels außerhalb der threads gebildeter Programme ausgeführt wird. Eine externe Synchronisation wird vorzugsweise für Datenstrukturen verwendet, welche von mehreren threads gleichzeitig benutzt werden. Für den Datentransfer zwischen einzelnen threads ist es üblich, diese intern zu synchronisieren. Es wird davon ausgegangen, dass hier eine interne Synchronisation einfacher zu realisieren ist und die entsprechenden Programme kürzer sind.
  • Ein Ziel derartiger Synchronisationsmechanismen ist es, dass sie möglichst vielfältig eingesetzt werden können, das heißt, dass sie von unterschiedlichsten threads verwendet werden können. Die oben erläuterten Reihen (Queues) sind ein Beispiel für sehr vielfältig einsetzbare Kommunikationsmechanismen. Sie erzeugen jedoch einen erheblichen Verwaltungsaufwand, da die Daten in entsprechende Pakete gepackt, diese Pakete mit entsprechenden Informationen versehen, von den Erzeuger-threads entsprechend versandt, von der Queue aufgenommen und vom Lesethread wieder aufgenommen, ausgelesen und zusammengesetzt werden müssen. Diese allgemeine Einsatzfähigkeit der Reihen wird durch einen hohen Verwaltungsaufwand erkauft.
  • Am schnellsten laufen threads auf unterschiedlichen Prozessoren ab, wenn sie mit einem asynchronen Datentransfer programmiert sind. Bei einem derartigen asynchronen Datentransfer kann z.B. ein thread eine Anfrage nach Daten ausgeben und während er auf den Empfang der Daten wartet, bereits eine andere Verarbeitung von Daten aufnehmen. Ein derart asynchroner Datentransfer ist hoch effizient, aber sehr schwer zu programmieren.
  • Ein Problem dieser auf mehrere threads verteilten Computerprogramme ist, dass ein Test, bei welchem die threads auf mehreren Prozessoren gleichzeitig laufen, schwer durchführbar ist, da je nachdem, wie sich die Verarbeitungsvorgänge der einzelnen threads zeitlich überlappen unterschiedliche Fehler einstellen können. Hierdurch kann es sein, dass ein Computerprogramm tausende Male richtig funktioniert und dann wieder ein nicht ohne weiteres vorhersehbarer Fehler auftritt. Für einen zuverlässigen Praxistest ist es deshalb notwendige Voraussetzung, derartige Synchronisationsverfahren mit einem Multi-CPU-Computer zu testen. Das sind Computer, die mehrere Prozessoren aufweisen, die gleichzeitig unterschiedliche threads abarbeiten können.
  • Ein Verfahren zum Synchronisieren von threads muß deshalb nicht nur einen effizienten Datentransfer und vielseitig einsetzbar sein, sondern möglichst einfach ausgebildet sein, damit kein. unverhältnismäßig großer Einsatz beim Testen des Computerprogramms notwendig ist.
  • Der Erfindung liegt deshalb die Aufgabe zugrunde, ein Verfahren zum Synchronisieren von threads eines Computerprogrammes zu schaffen, das vielfältig einsetzbar ist, einen sehr effizienten Datentransfer zwischen den threads erlaubt und zudem einfach ausgebildet ist.
  • Die Aufgabe wird durch ein Verfahren mit den Merkmalen des Anspruchs 1 gelöst. Vorteilhafte Ausgestaltungen der Erfindung sind in den Unteransprüchen angegeben.
  • In dem erfindungsgemäßen Verfahren werden threads eines Computerprogramms synchronisiert. Das Computerprogramm ist derart aufgebaut, daß die threads parallel auf unterschiedlichen Prozessoren eines Computers ablaufen können. Erzeuger-threads, die Daten für einen anderen thread erzeugen, schreiben diese jeweils in Pufferabschnitte flexibler Größe eines Puffers, wobei der letzte physikalische Pufferabschnitt nicht beschrieben wird und nach dem Beschreiben des vorletzten Pufferabschnitts wieder am Anfang des physikalischen Puffers mit dem Schreiben begonnen wird. Lese-threads, die Daten von einem anderen thread lesen, lesen die Daten aus dem Puffer aus. Zum Freigeben und Sperren der Schreibvorgänge und der Lesevorgänge werden Puffer-Dienstprogramme verwendet, wobei während dem Zugriff eines ersten Puffer-Dienstprogrammes auf den Puffer ein gleichzeitiger Zugriff auf den Puffer für ein zweites Puffer-Dienstprogramm verhindert wird. Die Pufferabschnitte des Puffers werden von den Puffer-Dienstprogrammen mit jeweils einem Flag versehen, durch das ein durchgehender, mit Daten belegbarer Speicherbereich erzeugt wird und mit dem jeweils Schreib- und Lesevorgänge der entsprechenden Pufferabschnitte steuerbar sind. Zusammen mit dem Flag wird eine Angabe über die Größe des jeweiligen Pufferabschnitts abgespeichert, so dass die einzelnen Pufferabschnitte unterschiedlich groß sein können. Beim Auslesen der Pufferabschnitte wird beim Erreichen des Endes des letzten beschriebenen Pufferabschnitts geprüft, ob am Anfang des Pufferspeichers gültige Daten stehen und gegebenenfalls diese Daten in den letzten physikalischen Pufferabschnitt derart kopiert werden, dass eine durchgehende Datenmenge gele sen werden kann. Das einem Pufferabschnitt zugeordnete Flag kann drei Zustände einnehmen, die anzeigen, ob Daten in den Pufferabschnitt geschrieben werden können, Daten aus dem Pufferabschnitt gelesen werden können oder die in den Pufferabschnitt geschriebenen Daten noch nicht zum Lesen freigegeben sind.
  • Das erfindungsgemäße Verfahren zum Synchronisieren von threads sieht somit einen Puffer vor, bei dem das Lesen und Schreiben mittels Flags gesteuert wird. Die erfindungsgemäße Programmstruktur ist sehr einfach ausgebildet, weshalb es auch auf Computern mit mehreren Prozessoren mit einem relativ geringen Aufwand getestet werden kann. Das erfindungsgemäße Verfahren ist sehr effizient, denn die Daten können von einem Erzeuger-thread. direkt in den Puffer geschrieben bzw. von einem Lese-thread direkt aus diesem gelesen werden. Eine Vor- bzw. Nachverarbeitung der geschriebenen bzw. gelesenen Daten ist nicht notwendig. Das erfindungsgemäße Verfahren ist zudem sehr effizient, da nur ein geringer Verwaltungsaufwand mit dem Setzen bzw. Löschen des Flags anfällt, so daß die Prozessorleistung eines Computers auf die wesentlichen Arbeiten des Datentransfers bzw. der Ausführung der threads konzentriert wird.
  • Nach einer bevorzugten Ausführungsform der Erfindung sind die einzelnen Pufferabschnitte im Speicherbereich des Computers unmittelbar hintereinander liegend angeordnet und zu den jeweili gen Pufferabschnitten sind zugeordnete Verwaltungsdaten, wie z.B. das Flag, die Größe des Pufferabschnittes oder der Datentyp in einem davon unabhängigen Speicherbereich gespeichert. Hierdurch wird ein durchgehender mit Daten belegter Speicherbereich geschaffen, der schnell und einfach ausgelesen bzw. mit neuen Daten beschrieben werden kann. Zudem erlaubt diese Ausbildung des Puffers, daß dieser mit Blöcken einer bestimmten Größe beschrieben und Blöcken einer anderen Größe gelesen werden kann. Hierdurch kann die Datentransferrate, die durch die Größe der Blöcke beeinflußt wird, an die entsprechenden Anforderungen, die sowohl auf der Seite der Erzeuger-threads als auch auf der Seite der Lese-threads hoch oder niedrig sein kann, entsprechend angepaßt werden.
  • Die Erfindung wird nachfolgend beispielhaft anhand der beiliegenden Zeichnungen näher erläutert. In den Zeichnungen zeigen:
  • 1 den Betrieb eines in mehrere threads aufgespalteten Computerprogramms gemäß dem erfindungsgemäßen Verfahren schematisch in einem Blockschaltbild,
  • 2 den Betrieb des Computerprogramms aus 1, wobei ein thread weggelassen wird,
  • 3 schematisch ein Beispiel für einen Puffer mit dem den jeweiligen Pufferabschnitten zugeordneten Flags in einer tabellarischen Darstellung,
  • 4 das Schreiben in den Puffer und das Lesen aus dem Puffer mit unterschiedlichen Blöcken schematisch in einem Blockschaltbild,
  • 5 das Lesen und Schreiben schematisch vereinfacht in einem Blockschaltbild, wobei das Blockschaltbild in drei Bereiche, den Bereich des Erzeuger-threads, der Synchronisations-Puffer-Klasse und dem Bereich des Lese-threads unterteilt ist und die Blöcke jeweils in dem Bereich angeordnet sind, in dem sie ausgeführt werden,
  • 6 bis 10 einzelne Puffer-Dienstprogramme nach einem ersten Ausführungsbeispiel jeweils in einem Flußdiagramm,
  • 11a und 11b ein gegenüber dem ersten Ausführungsbeispiel abgewandeltes Puffer-Dienstprogramm gemäß einem zweiten Ausführungsbeispiel der Erfindung in einem Flußdiagramm,
  • 12 ein weiteres gegenüber dem ersten Ausführungsbeispiel abgewandeltes Puffer-Dienstprogramm gemäß dem zweiten Ausführungsbeispiel der Erfindung in einem Flußdiagramm,
  • 13 einen Computer mit einem Prozessor in einem schematisch vereinfachten Blockschaltbild und
  • 14 einen Computer mit zwei Prozessoren in einem schematisch vereinfachten Blockschaltbild.
  • In 1 ist schematisch der Betrieb eines in mehrere threads P0 bis P3 aufgeteilten Computerprogramms dargestellt. Zur Veranschaulichung ist lediglich ein einfaches Computerprogramm schematisch dargestellt, dessen threads die Initialisierung P0, das Datenlesen P1, das Datenverarbeiten P2 und das Datenschreiben P3 ausführen. Der thread „Daten lesen" P1 muß Daten an den thread „Daten verarbeiten" P2 und dieser muß Daten an den thread „Daten schreiben" P3 weitergeben, weshalb zwischen den threads P1 und P2 ein Puffer PU1 und den threads P2 und P3 ein Puffer PU2 angeordnet sind.
  • Aus Sicht des threads „Daten verarbeiten" P2 ist der Puffer PU1 ein Eingabepuffer, der Daten in den thread P2 eingibt, und der Puffer PU2 ein Ausgabepuffer, der Daten des threads P2 aufnimmt. Mit dem erfindungsgemäßen Verfahren wird der Datentransfer DT von einem thread zu einem Puffer – z.B. von P1 zu PU1 oder von P2 zu PU2 – bzw. von einem Puffer zu einem thread – z.B. von PU1 zu P2 – lediglich durch eine Kommunikation zwischen dem jeweiligen Puffer und dem jeweiligen thread gesteuert. Dies ist in 1 durch die entgegen zum Datenhauptstrom verlaufenden Pfeile PF dargestellt.
  • Die Grundprinzipien der erfindungsgemäßen Steuerung des Datentransfers DT zwischen den threads und den Puffern werden nachfolgend anhand der 3 bis 5 näher erläutert.
  • Diese Steuerung bzw. Synchronisation des Datentransfers DT erfolgt mit einer Synchronisations-Puffer-Klasse. Der Begriff der „Klasse" ist in der objektorientierten Programmierung geprägt worden und bedeutet im Sinne der vorliegenden Patentanmeldung eine geschlossene Einheit, die in Feldern und Variablen gespeicherte Daten sowie Programme umfaßt. Die Synchronisations-Puffer-Klasse weist einen Speicherbereich, den Puffer, in dem ein oder mehrere Pufferabschnitte gespeichert sind, einen weiteren Speicherbereich, das Kontrollfeld, in dem Verwaltungsdaten für den Puffer gespeichert sind, und Puffer-Dienstprogramme auf. Die Puffer-Dienstprogramme sind Funktionen, d.h. ausführbare Programmteile. Beim erfindungsgemäßen Verfahren sind jedem Pufferabschnitt jeweils eine Gruppe von Verwaltungsdaten zugeordnet, die ein Flag (3), eine Angabe über die Größe des Pufferabschnittes und eine Angabe über den Inhalt der im Puffer gespeicherten Daten umfaßt. Das Flag ist eine Zustandsvariable, die drei Zustände einnehmen kann, nämlich „ungültig", „gültig" und „reserviert".
  • Ist das Flag „ungültig", so bedeutet dies, daß in dem zugehörigen Pufferabschnitt keine zum Lesen durch den Erzeuger-thread vorgesehene Daten enthalten sind. Ist das Flag „gültig" sind Daten in den zugehörigen Pufferabschnitt geschrieben worden, die vom Lese-thread gelesen werden können. Ist das Flag „reserviert", so bedeutet dies, daß der Erzeuger-thread bereits Daten in den zugehörigen Pufferabschnitt geschrieben hat, aber diese Daten noch nicht zum Lesen durch den Lese-thread freigegeben sind. Hierzu muß das Flag auf „gültig" gesetzt werden.
  • Die Synchronisations-Puffer-Klasse umfaßt ferner einige Puffer-Dienstprogramme wie z.B. GetToBufPntr, GetFromBufPntr, Release-ToBufPntr und ReleaseFromBufPntr.
  • 3 zeigt die Flags und Pufferabschnitte einer erfindungsgemäßen Synchronisations-Puffer-Klasse schematisch in einer tabellarischen Darstellung. Es sind insgesamt 8 Pufferabschnitte vorgesehen, welchen jeweils ein Flag zugeordnet ist. Der Pufferabschnitt 0 (oberster Pufferabschnitt in 3) enthält keine zum Lesen vorgesehenen Daten, weshalb dem zugehörigen Flag der Wert „ungültig" zugewiesen ist. Die weiteren Pufferabschnitte 1 bis 5 enthalten Daten, wobei die Pufferabschnitte 1 bis 3 gelesen werden können und die Pufferabschnitte 4 bis 5 vom Erzeuger-thread noch nicht freigegeben sind. Dementsprechend ist den den Pufferabschnitten 1 bis 3 zugeordneten Flags der Wert „gültig" und den den Pufferabschnitten 4 und 5 zugeordneten Flags der Wert „reserviert" zugeordnet. Die weiteren Pufferabschnitte 6 und 7 enthalten keine zum Lesen freigegebenen Daten, weshalb die ihnen zugeordneten Flags den Wert „ungültig" aufweisen. Ein Erzeuger-thread kann in die Pufferabschnitte 6, 7 und 0 Daten schreiben und ein Lese-thread kann aus den Pufferabschnitten 1 bis 3 Daten auslesen.
  • 5 zeigt schematisch das Zusammenwirken eines Erzeugerthreads und eines Lese-threads, der vom Erzeuger-thread in einer erfindungsgemäßen Synchronisations-Puffer-Klasse zwischengespeicherte Daten empfängt. Mit einem Schritt S1 startet der Erzeuger-thread. Mit einem Schritt S2 ist in 5 schematisch der Ablauf eines vorbestimmten Bereichs des Threads dargestellt, mit dem Daten für den Lese-thread erzeugt werden. Im Schritt S3 wird das Puffer-Dienstprogramm GetToBufPntr aufgerufen, das Bestandteil der Synchronisations-Puffer-Klasse ist. Mit dem Aufruf dieses Puffer-Dienstprogramms wird abgefragt, ob im Puffer ein Pufferabschnitt mit der Größe M1 zum Schreiben von Daten frei ist. Das Puffer-Dienstprogramm GetToBufPntr (M1) führt diese Abfrage aus und wartet gegebenenfalls solange bis der entsprechende Speicherbereich frei ist. Sobald der gewünschte Speicherbereich zur Verfügung steht, übergibt dieses Puffer-Dienstprogramm an den Erzeuger-thread einen Schreib-Zeiger und den Parameter M2, der die Größe des zur Verfügung stehenden Speicherbereichs angibt. M2 ist zumindest so groß wie M1. Der Schreib-Zeiger enthält die Adresse des Anfangs des zur Verfügung stehenden Speicherbereichs.
  • Mit der Anfangsadresse des zur Verfügung stehenden Speicherbereichs und dem maximal zur Verfügung stehenden Speicherbereich kann der Erzeuger-thread im Schritt S4 Daten direkt in den zur Verfügung stehenden Speicherbereich schreiben.
  • Wenn alle Daten in den Speicherbereich geschrieben sind, stellt dieser Speicherbereich einen Pufferabschnitt dar und wird im Schritt S5 das Puffer-Dienstprogramm ReleaseToBufPntr aufgerufen, mit dem das Flag des geschriebenen Pufferabschnittes entweder auf „gültig" oder auf „reserviert" gesetzt wird, je nachdem, ob die Daten zum Lesen durch den Lese-thread freigegeben sind oder nicht.
  • Mit den Schritten S6 und S8 sind weitere Verarbeitungsvorgänge des Erzeuger-threads symbolisch dargestellt. Mit dem dazwischen liegenden Schritt S7 wird das Puffer-Dienstprogramm SetResBuf-State (<Flagtyp>) aufgerufen, mit dem der im Schritt S5 beschriebene aber noch nicht freigegebene Pufferabschnitt entweder zum Lesen freigegeben wird, in dem das entsprechende Flag von „reserviert" auf „gültig" gesetzt wird, oder für den Lesethread „gelöscht" wird, indem das entsprechende Flag von „reserviert" auf „ungültig" gesetzt wird, wodurch dieser Speicherbereich erneut vom Erzeuger-thread beschrieben werden kann. Mit dem Schritt S9 wird der Programmablauf des Erzeuger-threads beendet.
  • Der Programmablauf des Lese-threads ist in 5 auf der rechten Seite dargestellt und beginnt mit dem Schritt S10. Die Darstellung in 5 ist rein schematisch und gibt nicht den korrekten Zeitablauf wider. Im Schritt S11 ist ein Abschnitt des Programmablaufs dargestellt, in dem ein Bedarf nach Daten des Erzeuger-threads entsteht. Der Lese-thread ruft deshalb das Puffer-Dienstprogramm GetFromBufPntr S12 auf. Dieses Puffer-Dienstprogramm fragt ab, ob im Puffer ein Pufferabschnitt mit Daten beschrieben ist, die zum Lesen durch den Lese-thread freigegeben sind. Falls keine Daten freigegeben sind, wartet dieses Puffer-Dienstprogramm solange bis eine entsprechende Anzahl von Daten geschrieben und freigegeben ist. Danach wird an den Lese-thread ein Lese-Zeiger und die Größe des Pufferabschnittes, der mit zum Lesen freigegebenen Daten beschrieben ist, ausgegeben. Der Lese-Zeiger enthält die Adresse des Anfangs des zum Lesen freigegebenen Pufferabschnittes.
  • Anhand dieses Lese-Zeigers und der Größe des zum Lesen freigegebenen Pufferabschnittes kann der Lese-thread im Schritt S13 die Daten unmittelbar aus dem Puffer auslesen.
  • Ist der Lesevorgang abgeschlossen, so ruft der Lese-thread das Puffer-Dienstprogramm ReleaseFromBufPntr S4 auf, mit dem der vom Lese-thread ausgelesene Pufferabschnitt zum erneuten Beschreiben freigegeben wird, das heißt, daß das entsprechende Flag von „gültig" auf „ungültig" gesetzt wird.
  • Der weitere vom Lese-thread ausgeführte Programmablauf ist schematisch mit S15 dargestellt. Mit dem Schritt S16 endet der Programmablauf des Lese-threads.
  • Nachfolgend werden anhand der 6 bis 12 die einzelnen Puffer-Dienstprogramme näher erläutert.
  • In 6 ist das Puffer-Dienstprogramm GetToBufPntr(M1) als Flußdiagramm dargestellt. Es beginnt mit dem Schritt S17, auf dem im Programmablauf der Beginn der Puffer-Synchronisation S18 folgt. Im Schritt S18 wird eine Standardfunktion des verwendeten Betriebssystems aufgerufen, mit dem ein gleichzeitiger Zugriff auf den Puffer und die zugehörigen internen Variablen der Synchronisations-Puffer-Klasse durch ein anderes Puffer-Dienstprogramm verhindert wird. Im darauffolgenden Schritt S19 wird der vom Erzeuger-thread übergebene Parameter M1, der den zum Schreiben benötigten Speicherplatz im Pufferabschnitt angibt, eingelesen.
  • Im Schritt S20 wird abgefragt, ob im Puffer ein Pufferabschnitt zum Beschreiben zur Verfügung steht. Ergibt die Abfrage im Schritt S20, dass grundsätzlich ein Pufferabschnitt zum Beschreiben frei ist, so geht der Programmablauf auf den Schritt S21 über, mit dem die Größe des freien Speicherplatzes im beschreibbaren Pufferabschnitt berechnet wird.
  • Im Schritt S22 wird abgefragt, ob der berechnete freie Speicherplatz M2 größer als oder gleich dem angefragten Speicherplatz M1 ist.
  • Ergibt diese Abfrage im Schritt S22, dass genügend freier Speicherplatz zur Verfügung steht, so wird im Schritt S23 an den Erzeuger-thread die erste Adresse des Pufferabschnittes als Schreib-Zeiger sowie die ermittelte Größe an freien Speicherplatz M2 ausgegeben.
  • Danach wird im Schritt S24 die Puffer-Synchronisation beendet, wodurch auch andere Puffer-Dienstprogramme wieder auf den Puffer und die internen Variablen der Synchronisations-Puffer-Klasse zugreifen können. Mit dem Schritt S25 wird das Puffer-Dienstprogramm GetToBufPntr beendet.
  • Ergibt die Abfrage im Schritt S20, dass grundsätzlich kein Pufferabschnitt zum Beschreiben frei ist, oder die Abfrage im Schritt S22, dass der zur Verfügung stehende freie Speicherplatz kleiner als der benötigte Speicherplatz ist, so geht der Programmablauf auf den Schritt S26 über, in dem abgefragt wird, ob der Schreib-Zeiger, das heißt, die erste Adresse des zu beschreibenden Pufferabschnittes, plus der angefragte Speicherplatz M1 das physikalische Ende des Puffers erreicht oder überschritten haben.
  • Falls das physikalische Ende erreicht ist, geht der Programmablauf auf den Schritt S27 über, in dem der Schreib-Zeiger auf den physikalischen Anfang des Puffers, das heißt, dass die erste Adresse des Puffers als physikalischer Anfang gespeichert wird. Im darauffolgenden Schritt S28 wird die Puffer-Synchronisation beendet und der Programmablauf geht zurück auf den Schritt S18, wodurch das Puffer-Dienstprogramm GetToBufPntr erneut begonnen wird.
  • Ergibt die Abfrage im Schritt S26, dass die Summe der Adresse des Schreib-Zeigers und des angefragten Speicherplatzes M1 nicht auf das physikalische Ende des Puffers oder darüber hinaus zeigt, so geht der Programmablauf auf den Schritt S29 über, mit dem die Puffer-Synchronisation beendet wird, da im Schritt S20 oder S22 bereits festgestellt worden ist, daß kein ausreichender Speicherplatz vorhanden ist. Im Schritt S30 wird ein Warteprogramm durchlaufen, das auf vorbestimmte Ereignisse (events) der weiteren Puffer-Dienstprogramme wartet und so lange den Programmablauf des Puffer-Dienstprogramms GetToBufPntr anhält. Im vorliegenden Fall wartet das Warteprogramm bis das Puffer-Dienstprogramm ReleaseToBufPntr einen Pufferabschnitt wieder freigibt. Beim Warten wird das Puffer-Dienstprogramm GetToBufPntr eingeschläfert (angehalten). Das Puffer-Dienstprogramm ReleaseToBufPntr erzeugt ein Signal (event), das das Puffer-Dienstprogramm GetToBufPntr wieder weckt (fortsetzt). Somit wird durch das Warten die Rechenleistung der CPU nicht beansprucht.
  • Da im Schritt S29 die Puffer-Synchronisation beendet worden ist, kann während des Warteprogramms ein anderer thread, insbesondere der Lese-thread auf den Puffer und die internen Variablen der Synchronisations-Puffer-Klasse zugreifen und im Puffer gespeicherte Daten auslesen. Hierdurch kann beschreibbarer Speicherplatz im Puffer geschaffen werden. Am Ende des Warteprogramms geht der Programmablauf wieder auf den Schritt S18 über, mit dem das Puffer-Dienstprogramm GetToBufPntr von Neuem beginnt. Der Programmablauf ist identisch zu dem oben erläuterten Programmablauf, weshalb eine erneute Beschreibung nicht notwendig ist.
  • Mit dem Dienstprogramm GetToBufPntr werden der Schreib-Zeiger und die zum Beschreiben zur Verfügung stehende Menge an Speicherplatz dem Erzeuger-thread mitgeteilt. Dieser kann dann direkt in diesen Speicherbereich die Daten schreiben (S4).
  • Mit dem Puffer-Dienstprogramm ReleaseToBufPntr(M3,<Datentyp>, <Flagtyp>) wird der Schreibvorgang beendet (8). Dieses Puffer-Dienstprogramm beginnt mit dem Schritt S31 und startet die Puffer-Synchronisation im Schritt S32. Dieser Schritt entspricht dem Schritt S18 des Puffer-Dienstprogramms GetToBufPntr aus (6). Im Schritt S33 werden die vom Erzeuger-thread gelieferten Parameter, wie der beschriebene Speicherplatz M3, Datentyp, Flagtyp eingelesen. Im Schritt S34 wird das Flag dieses Pufferabschnittes entsprechend dem eingelesenen Parameter auf „gültig" oder „reserviert" gesetzt. Danach wird im Schritt S35 der Datentyp im Kontrollfeld gespeichert. Typische Datentypen sind z.B. Daten, end of buffer, end of file oder dergleichen.
  • Im Schritt S36 wird der Schreib-Zeiger aktualisiert, indem zu dem bisherigen Schreib-Zeiger der Wert des beschriebenen Speicherplatzes addiert wird. Diese im Schreib-Zeiger abgespeicherte Adresse ist nun die erste freie Adresse nach dem beschriebenen Pufferabschnitt.
  • Im Schritt S37 wird die Puffer-Synchronisation beendet und daraufhin wird im Schritt S38 das Puffer-Dienstprogramm ReleaseTo-BufPntr beendet.
  • Mit dem Puffer-Dienstprogramm ReleaseToBufPntr wird somit der zuvor beschriebene Pufferabschnitt durch Setzen des Flags auf „gültig" oder „reserviert" entweder zum Lesen durch den Lesethread freigegeben oder zunächst reserviert, um dann später festzulegen, ob die Daten für das Lesen freigegeben werden oder verworfen werden.
  • Mit dem Puffer-Dienstprogramm SetResBufState kann ein oder mehrere reservierte Pufferabschnitte für das Lesen freigegeben oder verworfen werden (10). Mit den Schritten S39 und S40 wird das Puffer-Dienstprogramm SetResBufState gestartet und die Puffer-Synchronisation begonnen. Mit dem Schritt S41 wird der Flagwert „gültig" oder „ungültig" vom Erzeuger-thread übernommen. Danach wird S42 der oder die mit dem Flag „reserviert" markierten Pufferabschnitte mit dem im Schritt S41 übernommenen Flagwert markiert, so dass die darin gespeicherten Daten entweder zum Lesen freigegeben werden (Flag: gültig) oder verworfen werden (Flag: ungültig). Mit den Schritten S43 und S44 wird die Puffer-Synchronisation beendet und das Puffer-Dienstprogramm SetResBufState beendet.
  • Mit den drei oben erläuterten Puffer-Dienstprogrammen GetTo-BufPntr, ReleaseToBufPntr, SetResBufState kann ein Erzeugerthread, die von ihm erzeugten Daten in die Synchronisations-Puffer-Klasse schreiben und zum Lesen durch einen Lese-thread freigeben.
  • Das Lesen von Daten beginnt der Lese-thread durch Aufrufen des Puffer-Dienstprogramms GetFromBufPntr (7).
  • Das Dienstprogramm GetFromBufPntr beginnt mit dem Schritt S45 und startet im Schritt S46 die Puffer-Synchronisation, so dass kein anderer thread auf den Puffer und die internen Variablen der Synchronisations-Puffer-Klasse zugreifen kann.
  • Mit dem Schritt S47 wird überprüft, ob der Lese-Zeiger auf das Ende des physikalischen Puffers zeigt. Hierbei ist zu berück sichtigen, dass am Ende des physikalischen Puffers immer ein Pufferabschnitt ohne Daten steht, dem als Datentyp ein „end of buffer" zugeordnet ist. Dies bedeutet, dass die Abfrage im Schritt S47 lediglich abfragt, ob der Pufferabschnitt, auf dem der Lese-Zeiger zeigt, den Datentyp „end of buffer" enthält. Ist dies der Fall, so geht der Programmablauf auf den Anfang des Puffers über, das heißt, der Lese-Zeiger wird auf die erste Adresse des Puffers und somit den ersten Pufferabschnitt gesetzt S48. Danach geht der Programmablauf auf den Schritt S49 über. Falls sich bei der Abfrage aus S47 ergeben hat, dass der Lese-Zeiger nicht auf das Ende des Puffers zeigt, so geht der Programmablauf direkt auf den Schritt S49 über.
  • Im Schritt S49 wird abgefragt, ob das Flag des Pufferabschnittes, auf den der Lese-Zeiger zeigt, den Wert „gültig" besitzt. Falls dies der Fall ist, bedeutet dies, dass die in diesem Pufferabschnitt gespeicherten Daten zum Lesen freigegeben sind. In diesem Fall geht der Programmablauf auf den Schritt S50 über, mit dem der Lese-Zeiger, die Größe des Pufferabschnittes und der Datentyp an den Lese-thread übergeben wird. Dies erfolgt durch schreiben der entsprechenden Werte in drei Variablen, die beim Aufrufen von GetFromBufPntr vom Lese-thread an die Synchronisations-Puffer-Klasse übergeben werden.
  • Im darauffolgenden Schritt S51 wird die Puffer-Synchronisation und danach das Puffer-Dienstprogramm GetFromBufPntr beendet S52.
  • Sollte die Abfrage im Schritt S49 ergeben, dass die im Pufferabschnitt gespeicherten Daten nicht gültig sind, so geht der Programmablauf auf den Schritt S53 über, mit dem die Puffer-Synchronisation beendet wird. Im darauffolgenden Schritt S54 wird ein Warteprogramm ausgeführt. Da im vorhergegangenen Schritt S53 die Puffer-Synchronisation beendet worden ist, kann während der Ausführung des Warteprogramms der Erzeuger-thread Daten in den Puffer schreiben bzw. Daten zum Lesen freigeben, so dass es möglich ist, dass während des Warteprogramms für den Lese-thread lesbare Daten im Puffer erzeugt werden. Dieses Warteprogramm arbeitet genauso wie das des Puffer-Dienstprogramms GetToBufPntr, wobei es jedoch auf die Freigabe eines Pufferabschnittes durch das Puffer-Dienstprogramm ReleaseFromBufPntr wartet.
  • Nach Beendigung des Warteprogramms geht der Programmablauf zurück auf den Schritt S46, womit dieses Puffer-Dienstprogramm erneut begonnen wird. Der Ablauf ist der gleiche, wie er oben beschrieben ist, weshalb eine erneute Beschreibung nicht notwendig ist. Der Lese-Zeiger zeigt auf die zuerst eingeschriebenen Daten, die dementsprechend als erstes ausgelesen werden (FIFO-Puffer).
  • Mit dem Puffer-Dienstprogramm GetFromBufPntr wird somit vom Lese-thread die zum Lesen der Daten notwendigen Parameter, wie der Lese-Zeiger, die Größe des Pufferabschnittes und der Datentyp abgefragt. Anhand dieser Parameter kann der Lese-thread die Daten aus dem Puffer lesen.
  • Der Lesevorgang wird vom Lese-thread durch Aufrufen des Puffer-Dienstprogramms ReleaseFromBufPntr (9) beendet. Dieses Puffer-Dienstprogramm startet im Schritt S55 und beginnt die Puffer-Synchronisation im Schritt S56. Im Schritt S57 wird das Flag des zuletzt beschriebenen Pufferabschnittes auf „ungültig" gesetzt, das heißt, dass der Pufferabschnitt zum Beschreiben durch den Erzeuger-thread freigegeben ist.
  • Im Schritt S58 wird der Lese-Zeiger aktualisiert, das heißt, dass zu der Adresse des bisherigen Lese-Zeigers der Betrag der gelesenen Datenmenge addiert wird. Der Lese-Zeiger zeigt somit auf die erste Adresse des nächsten, noch nicht gelesenen Pufferabschnittes.
  • Im Schritt S59 wird die Puffer-Synchronisation und im Schritt S60 das Puffer-Dienstprogramm ReleaseFromBufPntr beendet.
  • In 11a und 11b und 12 sind Flussdiagramme der beiden Puffer-Dienstprogramme GetFromBufPntr und ReleaseFromBufPntr gezeigt, die das Lesen der Daten in Blöcken erlauben, deren Länge variabel ist und bezüglich der Länge der Pufferabschnitte abweicht.
  • Das Puffer-Dienstprogramm GetFromBufPntr startet mit dem Schritt S61 und beginnt im Schritt S62 die Puffer-Synchronisation. Im Schritt S63 wird vom Lese-thread der Parameter einer relativen Position eingelesen. Im folgenden Schritt S64 wird abgefragt, ob die Daten des Pufferabschnittes (auf den der Lese-Zeiger zeigt) gültig sind und ob das Ende des Puffers erreicht ist. Falls beides zutrifft geht der Programmablauf auf den Schritt S65 über, mit dem der Programmzeiger auf den physikalischen Anfang des Puffers gesetzt wird. Danach geht der Programmablauf auf den Schritt S66 über.
  • Ergibt die Abfrage im Schritt S64 hingegen, dass entweder die Daten ungültig sind oder das Ende vom Puffer erreicht ist, so geht der Programmablauf direkt auf den Schritt S66 über.
  • Im Schritt S66 wird abgefragt, ob die Daten gültig sind und ob die relative Position größer als oder gleich zu diesem Pufferabschnitt ist. Die relative Position ist eine relative Adresse bzw. Sprungadresse, die den Adresssprung vom Lese-Zeiger zum Beginn des jeweils auszulesenden Bereichs angibt. Diese relative Adresse entspricht einer Datenmenge, die in diesem Adressbereich gespeichert werden kann. Im Schritt S66 wird diese Datenmenge mit der Datenmenge des Pufferabschnittes verglichen. Ergibt die Abfrage im Schritt S66, dass die Daten gültig sind und die relative Position größer als oder gleich zum Pufferabschnitt ist, so bedeutet dies, dass der Lesevorgang die Grenze von einem zu einem anderen Pufferabschnitt überschritten hat, und dass Daten eines weiteren Pufferabschnittes ausgelesen werden sollen. Da das Flag dieses weiteren Pufferabschnittes bisher nicht geprüft worden ist, wird der Lese-Zeiger auf den Anfang des nächsten Pufferabschnittes gesetzt und die relative Position angepaßt S67 und die Puffer-Synchronisation beendet S68. Der Programmablauf geht dann vom Schritt S68 wieder auf den Schritt S62, so daß die oben erläuterten Verfahrensschritte von neuem ausgeführt und die Daten des weiteren Pufferabschnittes auf ihre Gültigkeit überprüft werden.
  • Ergibt die Abfrage im Schritt S66, dass die Daten nicht gültig sind, oder dass die relative Position kleiner als die Größe des Pufferabschnitts ist, so geht der Programmablauf auf den Schritt S69 über, in dem erneut die Gültigkeit der Daten überprüft wird. Sind die Daten nicht gültig, so geht der Programmablauf auf die Schritte S70 und S71 über, mit welchen die Puffer-Synchronisation beendet und ein Warteprogramm ausgeführt wird, das die Freigabe des Pufferabschnittes durch das Puffer-Dienstprogramm ReleaseToBufPntr abwartet. Die Schritte S69 bis S71 entsprechen den Schritten S43, S53, S54 der ersten Ausführungsform des Puffer-Dienstprogrammes GetFromBufPntr.
  • Ergibt die Abfrage im Schritt S69, dass die Daten gültig sind, so geht der Programmablauf auf den Schritt S72 über, in dem abgefragt wird, ob die Datenmenge des auszulesenden Datenblocks größer als der Pufferabschnitt ist. Ergibt die Abfrage im Schritt S72, dass die Datenmenge des auszulesenden Datenblocks nicht größer als der auszulesende Pufferabschnitt ist, so geht der Programmablauf auf den Schritt S73 über, mit dem die Parameter der Größe des auszulesenden Datenblocks und der Datentyp an den Lese-thread ausgegeben werden. Danach wird im Schritt S74 die Puffer-Synchronisation und im Schritt S75 das Puffer-Dienstprogramm GetFromBufPntr beendet.
  • Ergibt die Abfrage im Schritt S72, dass der auszulesende Datenblock größer als der Pufferabschnitt ist, so bedeutet dies, dass mit einem einzigen Datenblock Daten eines Pufferabschnittes und Daten eines weiteren Pufferabschnittes ausgelesen werden. Es wird deshalb im Schritt S76 abgefragt, ob die Daten des nächsten Pufferabschnittes gültig sind. Ergibt die Abfrage, dass die Daten nicht gültig sind, so geht der Programmablauf auf den Schritt S70 über, ansonsten geht der Programmablauf auf den Schritt S77 über, mit dem abgefragt wird, ob das Ende des Puffers erreicht ist. Ist das Ende des Puffers noch nicht erreicht, so können die Daten unmittelbar ausgelesen werden und der Programmablauf geht auf den Schritt S73 über. Ansonsten geht der Programmablauf auf den Schritt S78 über, mit dem geprüft wird, ob die Daten am Anfang des Puffers gültig sind. Sind diese Daten nicht gültig, so geht der Programmablauf wieder auf den Schritt S70 über, der zur Warteschlange im Schritt S71 führt. Ansonsten geht der Programmablauf auf den Schritt S79 über, mit dem die Daten vom Anfang des Puffers in den letzten an sich leeren Pufferabschnitt kopiert werden, der das Ende des Puffers bildet und mit einem „end of buffer" markiert ist.
  • Hierdurch kann über das Ende des letzten Puffers hinaus ein vollständiger Datenblock ausgelesen werden, weshalb der Programmablauf wieder auf den Schritt S73 übergeht, mit dem die entsprechenden Parameter an den Lese-thread ausgegeben werden.
  • Nach dem Ausführen von GetFromBufPntr kann der Lese-thread einen Block aus dem Puffer lesen.
  • Nach dem Lesen eines Blockes wird das Puffer-Dienstprogramm ReleaseFromBufPntr (12) aufgerufen. Dieses Puffer-Dienstprogramm beginnt im Schritt S80 und startet im Schritt S81 die Puffer-Synchronisation. Im Schritt S82 werden vom Lesethread die Parameter der relativen Position und der Größe des gelesenen Blockes eingelesen. Daraufhin wird abgefragt S83, ob die relative Position plus der Größe des eingelesenen Blockes größer als der Pufferabschnitt sind. Ist dies der Fall, so bedeutet dies, dass ein gesamter Pufferabschnitt gelesen worden ist. Der Programmablauf verzweigt dann auf den Schritt S84, in dem das Flag des gelesenen Pufferabschnittes auf „ungültig" gesetzt wird.
  • Im darauffolgenden Schritt S85 werden der Lese-Zeiger und die relative Position aktualisiert, wobei in den Lese-Zeiger die erste Adresse des auf den ausgelesenen Pufferabschnitt folgenden Pufferabschnitts eingesetzt wird und als relative Position die Differenz zwischen der auf den aus dem Puffer ausgelesenen Pufferabschnitt folgenden Adresse und dem neuen Lese-Zeiger gespeichert wird. Die Summe des neuen Lese-Zeigers und den relativen Position zeigen somit auf die erste Adresse des auf den ausgelesenen Pufferabschnitts folgenden Speicherbereiches im Puffer.
  • Im Schritt S86 wird die Puffer-Synchronisation und im Schritt S87 das Puffer-Dienstprogramm beendet.
  • Ergibt die Abfrage im Schritt S83, dass die Summe aus der relativen Position und der Größe des ausgelesenen Blockes kleiner als oder gleich zum Pufferabschnitt ist, so bedeutet dies, dass der Pufferabschnitt, aus dem ein Block gelesen worden ist, noch nicht vollständig ausgelesen ist. Deshalb kann das Flag des Pufferabschnittes noch nicht auf „ungültig" gesetzt werden, wodurch der Pufferabschnitt zur weiteren Beschreibung freigegeben werden würde und nicht mehr vollständig ausgelesen werden könnte.
  • Mit den in 11, 11b und 12 gezeigten Puffer-Dienstprogrammen können somit Datenblöcke ausgelesen werden, deren Größe sich von den gespeicherten Pufferabschnitten unterscheidet. Dies ist in 4 beispielhaft dargestellt. 4 zeigt einen Puffer mit insgesamt sechs Pufferabschnitten PA1 bis PA6. Im vorliegenden Ausführungsbeispiel weisen alle Pufferabschnitte die gleiche Größe auf. Es ist jedoch auch möglich, dass die einzelnen Pufferabschnitte unterschiedliche Größen besitzen. In die Pufferabschnitte PA4, PA5, PA1 und PA2 sind vom Erzeuger-thread Dateneinheiten N, N+1, N+2 und N+3 geschrieben worden. Dementsprechend sind die Flags dieser Pufferabschnitte PA4, PA5, PA1 und PA2 auf „gültig" gesetzt. Der Pufferabschnitt PA3 enthält keine zum lesen vorgesehenen Daten, weshalb dessen Flag auf „ungültig" gesetzt ist.
  • Der Pufferabschnitt PA6 enthält zunächst keine Daten und ist mit einem „end of buffer" markiert, das heißt, dass er das physikalische Ende des Puffers darstellt.
  • Zu Beginn des Lesevorgangs durch den Lese-thread steht der Lese-Zeiger auf der ersten Adresse des Pufferabschnittes PA4, der die ersten eingeschriebenen Daten enthält.
  • In 4 ist gezeigt, dass der Lese-thread Daten mittels vier Blöcken X, X+1, X+2 und X+3 ausliest. Diese Blöcke sind kleiner als die Pufferabschnitte. Nach dem Auslesen der Blöcke X und X+1 werden Daten aus dem Pufferabschnitt PA1 in den Pufferabschnitt PA6 kopiert, damit beim nächsten Lesen des Blockes X+2 beim Überschreiten der Grenze zwischen den Pufferabschnitten PA5 und PA6 eine durchgehende Datenmenge gelesen werden kann. Dieses Kopieren der Daten von PA1 auf PA6 wird im Schritt S79 des Puffer-Dienstprogrammes GetFromBufPntr (11) ausgeführt. Ist der Block X+2 gelesen, so wird festgestellt, dass der Lese-Zeiger auf das physikalische Ende des Puffers zeigt S64, weshalb der Lese-Zeiger auf den Anfang des Puffers gesetzt wird 565. Durch die relative Position wird sichergestellt, dass vom Pufferabschnitt PA1 lediglich die Daten ausgelesen werden, die nicht bereits durch den Block X+2 aus dem Pufferabschnitt PA6 gelesen worden sind.
  • Das obige Ausführungsbeispiel zeigt Blöcke, die kleiner als die Pufferabschnitte sind. Grundsätzlich ist es jedoch auch möglich, mit Blöcken auszulesen, die größer als die Pufferabschnitte sind. Die Blöcke können am obigen Ausführungsbeispiel die doppelte Größe der Pufferabschnitte besitzen.
  • Anhand der oben erläuterten Ausführungsbeispiele kann man gut erkennen, dass die Steuerung des Datentransfers zwischen zwei threads alleine durch die Synchronisations-Puffer-Klasse, das heißt dem Puffer, den dem Puffer zugeordneten Verwaltungsdaten, wie dem Flag, und den Puffer-Dienstprogrammen ausgeführt wird. Die threads müssen zur Gewährleistung eines fehlerfreien Daten transfers zum Schreiben und zum Lesen lediglich die Puffer-Dienstprogramme aufrufen, mit welchen in den threads die zum Lesen und Schreiben notwendigen Parameter übergeben werden und die einen unerlaubten Zugriff auf den Puffer verhindern.
  • Ein weiterer Vorteil des erfindungsgemäßen Verfahrens ist, dass durch die separate Datenschnittstelle zwischen jedem Puffer und dem thread das gesamte Computerprogramm schnell umstrukturiert werden kann, indem lediglich ein thread die Daten in einen anderen Puffer schreibt oder aus einem anderen Puffer liest. Dies lässt sich einfach und schnell durch Ändern eines entsprechenden Klassen-Zeigers bewerkstelligen. 2 zeigt eine derartige Änderung, bei der der Daten verarbeitende thread einfach entfernt worden ist, indem der thread „Daten schreiben" P3 seine Daten unmittelbar aus dem Eingabepuffer ausliest. Dies wird einfach durch Ändern des Zeigers des threads „Daten schreiben" P3 auf den Eingabepuffer ausgeführt.
  • Die Erfindung ist oben anhand von Ausführungsbeispielen näher erläutert worden, bei welchen jeweils ein Puffer zwischen zwei threads angeordnet ist, wobei jeweils ein Erzeuger-thread in dem Puffer Daten schreiben und ein Lese-thread aus dem Puffer Daten lesen kann. Im Rahmen der Erfindung ist es jedoch möglich, dass beispielsweise mehrere threads in einen Puffer schreiben bzw. aus einem Puffer lesen. Hierzu müssen die einzelnen Puffer-Dienstprogramme lediglich dahingehend abgewandelt werden, dass die threads nicht gleichzeitig auf den Puffer zugreifen können. Gegebenenfalls kann es zweckmäßig sein, mit dem Flag anzugeben, welche Daten für welchen thread vorgesehen sind.
  • Das erfindungsgemäße Verfahren ist zum Synchronisieren von threads vorgesehen, die auf einen Computer mit mehreren Prozessoren auf den einzelnen Prozessoren parallel ablaufen können. Das erfindungsgemäße Verfahren kann selbstverständlich auch auf einem Computer mit einem einzigen Prozessor ausgeführt werden.
  • Die Erfindung ist oben anhand eines Ausführungsbeispiels beschrieben, bei welchem Daten reserviert werden können. Im Rahmen der Erfindung ist es selbstverständlich auch möglich, daß das Flag lediglich auf die beiden Zustände „gültig" oder „ungültig" gesetzt werden kann. Bei einer solchen vereinfachten Ausführungsform entfällt das Puffer-Dienstprogramm SetResBuf-State.
  • Zum Initialisieren des Puffers ist ein entsprechendes Initialisationsprogramm vorgesehen. Mit diesem Initialisationsprogramm wird der Speicherbereich festgelegt, den der Puffer in Anspruch nimmt. Er kann je nach Bedarf eingestellt werden. Die Anzahl der Pufferabschnitte kann dementsprechend variieren, zumal die Länge der einzelnen Pufferabschnitte unterschiedlich sein kann.
  • Das erfindungsgemäße Verfahren kann als Bestandteil eines Betriebssystems eines Computers realisiert sein. Es kann daher als auf einem Datenträger speicherbares oder über ein Datennetz übertragbares Computerprogramm ausgebildet sein. Die Puffereinrichtung kann insbesondere als Speicherbaustein ausgebildet sein. Es ist jedoch auch möglich, eine Puffereinrichtung mit einer Hardwareschaltung vorzusehen, z.B. einen anwenderspezifischen integrierten Schaltkreis (ASIC) mit entsprechend integrierten Pufferspeichern, die das erfindungsgemäße Verfahren ausführt.
  • In den 13 und 14 ist jeweils schematisch vereinfacht ein Computer Co mit einem Betriebssystem BS dargestellt, worin das erfindungsgemäße Verfahren integriert ist. Der Computer weist entweder einen einzigen Prozessor (CPU in 13) oder zwei Prozessoren (CPU1 und CPU2 in 14) auf. Die Computer besitzen jeweils einen Permanentspeicher P-Sp und einen Arbeitsspeicher RAM. Der Permanentspeicher P-Sp wird beispielsweise durch ein Festplattenlaufwerk, ein Diskettenlaufwerk und/oder einen ROM-Speicher dargestellt. Der Arbeitsspeicher RAM ist typischerweise ein Halbleiterspeicher. Der bzw. die Prozessoren kommunizieren in den dargestellten Ausführungsbei spielen mit dem Permanentspeicher P-Sp und dem Arbeitsspeicher RAM über einen Datenbus B.
  • Bevor einer der beiden Computer gestartet wird, ist das Betriebssystem BS und das vollständige Computerprogramm Co-Pr im Permanentspeicher P-Sp gespeichert. Beim Starten des Computers Co und beim Aufrufen des Computerprogramms Co-Pr durch einen Benutzer werden die zur Ausführung benötigten Teile des Betriebssystems BS und des Computerprogramms Co-Pr in den Arbeitsspeicher RAM geladen, auf den der bzw. die Prozessoren CPU, CPU1, CPU2 zum Ausführen derselben zugreifen.
  • Das Betriebssystem umfaßt Puffer-Programme Pu-Pr, wie z.B. ein Initialisationsprogramm und die Puffer-Dienstprogramme. Das Initialisationsprogramm wird z.B. nach dem Starten des Computers aufgerufen, wodurch im Arbeitsspeicher ein Abschnitt für den Puffer Pu reserviert wird. In den dargestellten Ausführungsformen ist der Puffer Pu im Bereich des Betriebssystems BS angeordnet. Es ist jedoch auch möglich, den Puffer in einem vom Betriebssystem BS unabhängigen Speicherabschnitt des Arbeitsspeichers auszubilden.
  • Bei dem Computer Co nach 13, der einen einzigen Prozessor aufweist, werden alle threads auf dem einen einzigen Prozessor ausgeführt. Bei dem Computer Co nach 14 mit zwei Prozessoren werden die threads auf die beiden Prozessoren verteilt, d.h. ein Teil der threads wird auf einem Prozessor und der andere Teil auf dem anderen Prozessor ausgeführt. Diese Aufteilung auf unterschiedliche Prozessoren erfolgt selbsttätig durch das Betriebssystem BS.
  • Die Software (Betriebssystem BS und Computer-Programm Co-PR) der beiden in 13 und 14 dargestellten Computer ist identisch. Das Betriebssystem erkennt die mehreren Prozessoren gemäß 14 und führt dann diese Aufteilung selbsttätig durch.
  • Geeignete Betriebssysteme, in die das erfindungsgemäße Verfahren integriert werden kann bzw. unter denen threads zur Durchführung des erfindungsgemäßen Verfahrens ablaufen können, sind Windows NT und Mehrprozessor-Versionen von UNIX.
  • Verfahrensschritte
  • S1
    Anfang
    S2
    Teil einer Programmausführung
    S3
    GetToBufPntr
    S4
    Daten in den Puffer schreiben
    S5
    ReleaseToBufPntr
    S6
    Teil einer Programmausführung
    S7
    SetResBufState
    S8
    Teil einer Programmausführung
    S9
    Ende
    S10
    Anfang
    S11
    Teil einer Programmausführung
    S12
    GetFromBufPntr
    S13
    Daten vom Puffer lesen
    S14
    ReleaseFromBufPntr
    S15
    Teil einer Programmausführung
    S16
    Ende
    S17
    Anfang
    S18
    Beginn der Puffer-Synchronisation
    S19
    Parameterübergabe
    S20
    Abfrage: Steht ein Pufferabschnitt zum Beschreiben zur Verfügung?
    S21
    Berechnung der Größe des zur Verfügung stehenden Speicherplatzes
    S22
    Abfrage: Zur Verfügung stehender Speicherplatz > = angefragter Speicherplatz?
    S23
    Ausgabe von Parametern
    S24
    Ende der Puffer-Synchronisation
    S25
    Ende
    S26
    Abfrage: Ende vom Puffer?
    S27
    Gehe zum Anfang vom Puffer
    S28
    Ende der Puffer-Synchronisation
    S29
    Ende der Puffer-Synchronisation
    S30
    Warteprogramm
    S31
    Anfang
    S32
    Beginn der Puffer-Synchronisation
    S33
    Einlesen von Parameter
    S34
    Setze Flag (gültig/reserviert)
    S35
    Speicherdatentyp
    S36
    Aktualiesiere Schreib-Zeiger
    S37
    Ende Puffer-Synchronisation
    S38
    Ende
    S39
    Anfang
    S40
    Beginn der Puffer-Synchronisation
    S41
    Einlesen von Parametern
    S42
    Setze Flag (gültig/ungültig)
    S43
    Ende der Puffer-Synchronisation
    S44
    Ende
    S45
    Anfang
    S46
    Beginn der Puffer-Synchronisation
    547
    Abfrage: Ende vom Puffer?
    S48
    Gehe zum Anfang vom Puffer
    S49
    Abfrage: Daten gültig?
    S50
    Parameter ausgeben
    S51
    Ende der Puffer-Synchronisation
    S52
    Ende
    S53
    Ende der Puffer-Synchronisation
    S54
    Warteprogramm
    S55
    Anfang
    S56
    Beginn der Puffer-Synchronisation
    S57
    Setze Flag auf „ungültig"
    S58
    Aktualisiere Lese-Zeiger
    S59
    Ende der Puffer-Synchronisation
    S60
    Ende
    S61
    Anfang
    S62
    Beginn der Puffer-Synchronisation
    S63
    Parameter einlesen
    S64
    Abfrage: Daten gültig & Ende von Puffer?
    S65
    Gehe zum Anfang vom Puffer
    S66
    Daten gültig & relative Position > = Pufferabschnitt?
    S67
    Aktualisiere Schreib-Zeiger
    S68
    Ende der Puffer-Synchronisation
    S69
    Abfrage: Daten gültig?
    S70
    Ende der Puffer-Synchronisation
    S71
    Warteprogramm
    S72
    Abfrage: Größe des auszulesenden Datenblocks > Pufferabschnitt?
    S73
    Übergabe von Parametern
    S74
    Ende der Puffer-Synchronisation
    S75
    Ende
    S76
    Abfrage: Sind die Daten des nächsten Pufferabschnittes gültig?
    S77
    Abfrage: Ende vom Puffer?
    S78
    Abfrage: Sind die Daten am Anfang des Puffers gültig?
    S79
    Kopiere Daten vom Anfang des Puffers zum Ende
    S80
    Anfang
    S81
    Beginn der Puffer-Synchronisation
    S82
    Einlesen von Parametern
    S83
    Abfrage: Relative Position & Blockgröße > Pufferabschnitt?
    S84
    Setze Flag auf "ungültig"
    S85
    Aktualisiere Lese-Zeiger und relative Position
    S86
    Ende der Puffer-Synchronisation
    S87
    Ende

Claims (20)

  1. Verfahren zum Synchronisieren von threads (PO, P1, P3) eines Computerprogramms (Co-Pr), wobei (a) in dem in threads aufgeteilten Computerprogramm (Co-Pr) Erzeuger-threads (P1, P2), die Daten für einen anderen thread erzeugen, diese Daten jeweils in Pufferabschnitte (PA1 – PA6) flexibler Größe eines Puffers (Pu) schreiben, wobei der letzte physikalische Pufferabschnitt (PA6) nicht beschrieben wird und nach dem Beschreiben des vorletzten Pufferabschnitts (PA5) wieder am Anfang des physikalischen Puffers mit dem Schreiben begonnen wird und wobei Lese-threads (P2, P3) die erzeugten Daten aus dem Puffer (Pu) auslesen, (b) zum Freigeben und Sperren der Schreibvorgänge und der Lesevorgänge Puffer-Dienstprogramme (S5, S7, S14) verwendet werden, (c) während dem Zugriff eines ersten Puffer-Dienstprogrammes auf den Puffer (Pu) ein gleichzeitiger Zugriff auf den Puffer (Pu) für ein zweites Puffer-Dienstprogramm verhindert wird, (d) die Pufferabschnitte (PA1 – PA6) von den Puffer-Dienstprogrammen (S5, S7, S14) mit jeweils einem Flag versehen werden, durch das ein durchgehender, mit Daten belegbarer Speicherbereich erzeugt wird und mit dem jeweils Schreib- und Lesevorgänge der entsprechenden Pufferabschnitte (PA1 – PA6) steuerbar sind, (e) zusammen mit dem Flag eine Angabe über die Größe des jeweiligen Pufferabschnitts (PA1 – PA6) abgespeichert wird, so dass die einzelnen Pufferabschnitte (PA1 – PA6) unterschiedlich groß sein können, (f) beim Auslesen der Pufferabschnitte beim Erreichen des Endes des letzten beschriebenen Pufferabschnitts geprüft wird, ob am Anfang des Pufferspeichers gültige Daten stehen und gegebenenfalls diese Daten in den letzten physikalischen Pufferabschnitt (PA6) derart kopiert werden, dass eine durchgehende Datenmenge gelesen werden kann und (g) dass das einem Pufferabschnitt (PA1 – PA6) zugeordnete Flag drei Zustände (ungültig, gültig, reserviert) einnehmen kann, die anzeigen, ob (g1) Daten in den Pufferabschnitt (PA1 – PA6) geschrieben werden können, (g2) Daten aus dem Pufferabschnitt (PA1 – PA6) gelesen werden können oder (g3) die in den Pufferabschnitt (PA1 – PA6) geschriebenen Daten noch nicht zum Lesen freigegeben sind.
  2. Verfahren nach Anspruch 1, dadurch gekennzeichnet, dass für jeweils zwei threads (P1, P2; P2, P3) ein gemeinsamer Puffer (PU1, PU2) vorgesehen ist, wobei einer der beiden threads (P1; P2) in den gemeinsamen Puffer (PU1, PU2) Daten schreibt und der andere thread (P2; P3) Daten aus dem Puffer (PU1, PU2) liest.
  3. Verfahren nach Anspruch 1 oder 2, dadurch gekennzeichnet, dass die Daten, die zuerst in den Puffer (PU) geschrieben werden auch als erste wieder ausgelesen werden (FIFO-Puffer).
  4. Verfahren nach einem der Ansprüche 1 bis 3, dadurch gekennzeichnet, dass das einem Pufferabschnitt (PA1 – PA6) zugeordnete Flag zumindest zwei Zustände (gültig, ungültig) einnehmen kann, die anzeigen, ob Daten in den Pufferabschnitt (PA1 – PA6) geschrieben oder aus dem Pufferabschnitt (PA1 – PA6) gelesen werden können.
  5. Verfahren nach Anspruch 4, dadurch gekennzeichnet, dass das einem Pufferabschnitt (PA1 – PA6) zugeordnete Flag einen weiteren Zustand (reserviert) einnehmen kann, der anzeigt, dass die in den Pufferabschnitt (PA1 – PA6) geschriebenen Daten noch nicht zum Lesen freigegeben sind.
  6. Verfahren nach einem der Ansprüche 1 bis 5, dadurch gekennzeichnet, dass die Flags in einem von den die Daten enthaltenden Pufferabschnitten (PA1 – PA6) unabhängigen Speicherabschnitt (Kontrollfeld) gespeichert sind, und die die Daten enthaltenden Pufferabschnitte (PA1 – PA6) aufeinanderfolgend abgespeichert sind.
  7. Verfahren nach einem der Ansprüche 1 bis 6, dadurch gekennzeichnet, dass zusammen mit dem Flag eine Angabe über die Größe des jeweiligen Pufferabschnitts (PA1 – PA6) abgespeichert wird, so dass die einzelnen Pufferabschnitte (PA1 – PA6) unterschiedlich groß sein können.
  8. Verfahren nach einem der Ansprüche 1 bis 7, dadurch gekennzeichnet, dass zusammen mit den Flags jeweils eine Angabe über den Typ der in dem jeweiligen Pufferabschnitt (PA1 – PA6) gespeicherten Daten gespeichert wird.
  9. Verfahren nach einem der Ansprüche 1 bis 8, dadurch gekennzeichnet, dass von den Puffer-Dienstprogrammen (S3: GetToBufPntr, S12: GetFromBufPntr) ein Lese-Zeiger oder ein Schreib-Zeiger an den jeweiligen thread auf eine entsprechende Anfrage ausgegeben wird, wobei der Lese-Zeiger die Adresse des Anfangs des beschreibbaren Pufferabschnittes (PA3) und der Schreib-Zeiger die Adresse des Anfangs des lesbaren Pufferabschnittes (PA4) enthalten.
  10. Verfahren nach Anspruch 9, dadurch gekennzeichnet, dass mit der Ausgabe eines Zeigers auch eine Angabe über den zum Schreiben oder zum Lesen zur Verfügung stehenden Speicherbereich ausgegeben wird.
  11. Verfahren nach Anspruch 9 oder 10, dadurch gekennzeichnet, dass das eine Anfrage nach einem Schreib-Zeiger oder einem Lese-Zeiger bearbeitende Puffer-Dienstprogramm (S3: GetToBufPntr, S12: GetFromBufPntr) auch eine Anfrage nach einer bestimmten Größe des zum Schreiben bzw. zum Lesen zur Verfügung stehenden Pufferabschnittes (PA1 – PA6) bearbeitet, und falls ein Pufferabschnitt (PA1 – PA6) mit der notwendigen Größe nicht zur Verfügung steht, wird ein Warteprogramm (S30, S54) ausgeführt und dann die Größe des zur Verfügung stehenden Pufferabschnitts (PA1 – PA6) erneut überprüft, wobei das Warteprogramm (S30, S54) wiederholt ausgeführt wird, bis der notwendige Pufferabschnitt (PA1 – PA6) zur Verfügung steht.
  12. Verfahren nach Anspruch 11, dadurch gekennzeichnet, dass das Warteprogramm (S30, S54) das entsprechende Puffer-Dienstprogramm einschläfert, das durch ein von einem anderen Puffer-Dienstprogramm (S5, S7, S14) erzeugtes Signal geweckt wird.
  13. Verfahren nach Anspruch 11 oder 12, dadurch gekennzeichnet, dass während des Ausführens des Warteprogramms (S30, S54) der Zugriff auf die Pufferabschnitte (PA1 – PA6) und die zugehörigen Speicherabschnitte (Kontrollfeld) freigegeben wird, so dass ein thread, der nicht die Anfrage an den Puffer (PU) gerichtet hat, darauf zugreifen kann.
  14. Verfahren nach einem der Ansprüche 9 bis 13, dadurch gekennzeichnet, dass, falls das eine Anfrage nach einem einem Lese-Zeiger bearbeitende Puffer-Dienstprogramm (S12: GetFromBufPntr) feststellt, dass am Ende eines dem Puffer (PU) als Datenspeicher zugeordneten Speicherbereichs (PA6) Daten benötigt werden, die am Anfang des Speicherbereichs (PA1) stehen, diese Daten vom Puffer-Dienstprogramm an das Ende des Speicherbereichs kopiert werden (S79).
  15. Verfahren nach einem der Ansprüche 1 bis 14, dadurch gekennzeichnet, dass nach dem Lesen (S13) bzw. Schreiben (S4) von Daten durch einen thread von dem jeweiligen thread ein Puffer-Dienstprogramm (S5, S14) aufgerufen wird, das den Lese- bzw. Schreib-Zeiger auf den aktuellen Wert setzt, und das Flag des zuletzt gelesenen oder beschriebenen Pufferabschnittes entsprechend setzt.
  16. Verfahren nach einem der Ansprüche 1 bis 15, dadurch gekennzeichnet, daß die threads (P1 – P3) auf unterschiedlichen Prozessoren (CPU1, CPU2) eines Computers ausgeführt werden.
  17. Betriebssystem für einen Computer (Co) mit mehreren Prozessoren (CPU1, CPU2), das die Synchronisation von threads (P1 – P3) mittels einer Pufferklasse, die einen Puffer (PU) und Puffer-Dienstprogramme (Pu-Pr: S3, S5, S7, 512, S14) umfaßt, nach einem Verfahren nach einem oder mehreren der Ansprüche 1 bis 16 ausführt.
  18. Computer mit mehreren Prozessoren, gekennzeichnet durch ein Betriebssystem (BS) nach Anspruch 17.
  19. Vorrichtung zum Synchronisieren von threads eines Computerprogramms, wobei die threads (P1 – P3) parallel ablaufen können, umfassend eine Puffereinrichtung (PU), in die ein Erzeuger-thread (P1, P2) Daten schreiben und aus der ein Lesethread (P2, P3) Daten lesen kann, und eine Pufferverwaltungseinrichtung, die für jeweils einen Pufferabschnitt (PA1 – PA6) ein Flag aufweist, das Lese- und Schreibvorgänge des entsprechenden Pufferabschnitts steuert, wobei die Flags von der Pufferverwaltungseinrichtung gesetzt werden, wobei die Vorrichtung ein Verfahren nach einem der Ansprüche 1 – 16 ausführt.
  20. Computerprogramm umfassend threads, das ein Verfahren nach einem der Ansprüche 1 bis 16 ausführt.
DE19957594A 1999-11-30 1999-11-30 Verfahren zum Synchronisieren von threads eines Computerprogramms Expired - Fee Related DE19957594B4 (de)

Priority Applications (3)

Application Number Priority Date Filing Date Title
DE19957594A DE19957594B4 (de) 1999-11-30 1999-11-30 Verfahren zum Synchronisieren von threads eines Computerprogramms
PCT/EP2000/012048 WO2001040931A2 (de) 1999-11-30 2000-11-30 Verfahren zum synchronisieren von programmabschnitten eines computerprogramms
US10/148,376 US7266825B2 (en) 1999-11-30 2000-11-30 Method for synchronizing program sections of a computer program

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
DE19957594A DE19957594B4 (de) 1999-11-30 1999-11-30 Verfahren zum Synchronisieren von threads eines Computerprogramms

Publications (2)

Publication Number Publication Date
DE19957594A1 DE19957594A1 (de) 2001-06-07
DE19957594B4 true DE19957594B4 (de) 2004-08-26

Family

ID=7930854

Family Applications (1)

Application Number Title Priority Date Filing Date
DE19957594A Expired - Fee Related DE19957594B4 (de) 1999-11-30 1999-11-30 Verfahren zum Synchronisieren von threads eines Computerprogramms

Country Status (3)

Country Link
US (1) US7266825B2 (de)
DE (1) DE19957594B4 (de)
WO (1) WO2001040931A2 (de)

Families Citing this family (15)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
DE10123377B4 (de) * 2001-05-14 2011-07-14 Océ Printing Systems GmbH, 85586 Verfahren zum Lesen von auf einem Datenband gespeicherter Daten und Lesevorrichtung
US7321997B2 (en) * 2004-03-30 2008-01-22 Intel Corporation Memory channel self test
KR101216520B1 (ko) 2004-06-30 2013-01-18 보다폰 그룹 피엘씨 연계 동작 방법 및 이동통신 단말장치
DE102005026256A1 (de) * 2005-06-08 2006-12-14 OCé PRINTING SYSTEMS GMBH Verfahren zum Durchführen des Datentransfers zwischen Programmelementen eines Prozesses, Puffer Objekt zum Durchführen des Datentransfers, sowie Drucksystem
JP4861480B2 (ja) * 2006-09-22 2012-01-25 オーセ プリンティング システムズ ゲゼルシャフト ミット ベシュレンクテル ハフツング 印刷データの自動的な伝送、特に印刷ジョブのミラーリングのための方法及びシステム
EP3922220A1 (de) * 2008-01-29 2021-12-15 Implantica Patent Ltd Vorrichtung zur behandlung von gerd mit einer stimulationsvorrichtung
DE102008037651B4 (de) 2008-08-14 2010-08-19 OCé PRINTING SYSTEMS GMBH Verfahren zur Kommunikation zwischen zwei unveränderbaren Anwendungsprogrammen und Computerprogrammen
US20110218440A1 (en) * 2008-11-14 2011-09-08 Hitachi Medical Corporation Ultrasonic diagnostic apparatus and signal processing method in ultrasonic diagnostic apparatus
US8528001B2 (en) * 2008-12-15 2013-09-03 Oracle America, Inc. Controlling and dynamically varying automatic parallelization
US9411568B2 (en) * 2010-04-15 2016-08-09 Microsoft Technology Licensing, Llc Asynchronous workflows
JP2012128778A (ja) * 2010-12-17 2012-07-05 Sony Corp データ転送装置、メモリ制御装置、およびメモリシステム
US10203934B2 (en) 2012-07-11 2019-02-12 Intel Corporation Parallell processing of a single data buffer
US9425953B2 (en) 2013-10-09 2016-08-23 Intel Corporation Generating multiple secure hashes from a single data buffer
TWI594245B (zh) * 2016-02-02 2017-08-01 慧榮科技股份有限公司 資料寫入工作排程方法以及使用該方法的裝置
US10976965B1 (en) * 2020-10-14 2021-04-13 First Capitol Consulting, Inc. Optimization of in-memory processing of data represented by an acyclic graph so that the removal and re-materialization of data in selected nodes is minimized

Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
DE19857332C1 (de) * 1998-12-11 2000-06-15 Siemens Ag Verfahren zur Synchronisation von Prozessen

Family Cites Families (15)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
AU501600B2 (en) * 1973-11-30 1979-06-28 Compagnie Internationale Pour L'informatique Cii Multiprogramming computer system
JPS5971562A (ja) * 1982-10-18 1984-04-23 Hitachi Ltd 時分割計算機システムの制御方式
NL8501143A (nl) * 1985-04-19 1986-11-17 Philips Nv Kommunikatiesysteem voorzien van een eerst-in-eerst-uit-buffer.
JP2594979B2 (ja) * 1987-10-23 1997-03-26 株式会社日立製作所 マルチプロセツサシステム
US5410654A (en) * 1991-07-22 1995-04-25 International Business Machines Corporation Interface with address decoder for selectively generating first and second address and control signals respectively in response to received address and control signals
US5293613A (en) * 1991-08-29 1994-03-08 International Business Machines Corporation Recovery control register
CA2107299C (en) * 1993-09-29 1997-02-25 Mehrad Yasrebi High performance machine for switched communications in a heterogenous data processing network gateway
US5742806A (en) * 1994-01-31 1998-04-21 Sun Microsystems, Inc. Apparatus and method for decomposing database queries for database management system including multiprocessor digital data processing system
US5758149A (en) * 1995-03-17 1998-05-26 Unisys Corporation System for optimally processing a transaction and a query to the same database concurrently
US5710923A (en) 1995-04-25 1998-01-20 Unisys Corporation Methods and apparatus for exchanging active messages in a parallel processing computer system
DE69614671T2 (de) * 1996-01-09 2002-07-04 Koninkl Philips Electronics Nv Verfahren und system zum synchronisieren von gleichzeitigen sequentiellen prozessen mit hilfe von intra-prozess-korrigier- und inter-prozess-adaptier- operationen
JP3532037B2 (ja) 1996-07-31 2004-05-31 富士通株式会社 並列計算機
US6385658B2 (en) * 1997-06-27 2002-05-07 Compaq Information Technologies Group, L.P. Method and apparatus for synchronized message passing using shared resources
US6047391A (en) * 1997-09-29 2000-04-04 Honeywell International Inc. Method for strong partitioning of a multi-processor VME backplane bus
US6188699B1 (en) * 1997-12-11 2001-02-13 Pmc-Sierra Ltd. Multi-channel encoder/decoder

Patent Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
DE19857332C1 (de) * 1998-12-11 2000-06-15 Siemens Ag Verfahren zur Synchronisation von Prozessen

Non-Patent Citations (3)

* Cited by examiner, † Cited by third party
Title
NIERATSCHKER, Karl: Vom Echtzeitkern zum kompletten Betriebssystem, In: Design & Elektronik, Ausgabe 26 vom 22.12.1989, S. 44-47 *
TANENBAUM, Andrew: Moderne Betriebssysteme, Carl Hanser Verlag München Wien, 1994, ISBN 3-446-17472-9, S. 40-54 *
ZILKER: Praxis des Multitasking, Franzis-Verlag GmbH, München, 1987, ISBN 3-7723-8561-3, S. 45-61 *

Also Published As

Publication number Publication date
US7266825B2 (en) 2007-09-04
US20030041086A1 (en) 2003-02-27
WO2001040931A2 (de) 2001-06-07
WO2001040931A3 (de) 2002-11-07
DE19957594A1 (de) 2001-06-07

Similar Documents

Publication Publication Date Title
DE19957594B4 (de) Verfahren zum Synchronisieren von threads eines Computerprogramms
DE2645537C2 (de)
DE68926775T2 (de) System und Verfahren für eine allgemeine Schnittstelle für Anwendungsprogramme
DE2455803C2 (de) Mehrprozessor-Datenverarbeitungsanlage
DE3852115T2 (de) Simulationsverfahren für Programme.
DE3882772T2 (de) Vektorprozessor angepasst zum Sortieren von Vektordaten.
DE3638572C2 (de)
DE3508291A1 (de) Realzeit-datenverarbeitungssystem
DE2317417A1 (de) Takt- und steuerlogikschaltung
DE19654593A1 (de) Umkonfigurierungs-Verfahren für programmierbare Bausteine zur Laufzeit
DE3113195A1 (de) &#34;speicheradressiervorrichtung&#34;
DE2449547A1 (de) Computer- und datenverarbeitungsanlage
DE69026764T2 (de) Verfahren zur Datenübertragung mit hoher Geschwindigkeit
DE1499182B2 (de) Datenspeichersystem
DE2755616A1 (de) Asymmetrischer multiprozessor
DE2101949A1 (de) Verfahren zum Schutz von Datengruppen in einer Multiprocessing-Datenverarbeitungsanlage
DE2912073A1 (de) Stapelspeicheranordnung zur kurzzeitigen speicherung von informationen bei nichtabsetzbarkeit dieser informationen in einem datenverarbeitungssystem
DE2144051A1 (de) Programm Unterbrechungsanordnung für eine Datenverarbeitungsanlage
DE2458286A1 (de) Datenverarbeitungssystem zum verschieben von datenfeldern mit verschiedenen strukturen
DE69031361T2 (de) Taktsignalgeneratorsystem
DE60221515T2 (de) Speichersystem für schleifenbeschleunigung nach wunsch
DE2519195C2 (de) Assoziativspeicher
DE3843638C2 (de)
EP0970426B1 (de) Abhängigkeitssteuerung für überlappende speicherzugriffe
DE69126360T2 (de) Vorlagenerkennungssystem mit Schaltungen mit horizontalem/vertikalem Lauflängeglättungsalgorithmus und einer Schaltung zur Bereichsaufteilung von Vorlagen

Legal Events

Date Code Title Description
OP8 Request for examination as to paragraph 44 patent law
8364 No opposition during term of opposition
R082 Change of representative

Representative=s name: PATENTANWAELTE SCHAUMBURG, THOENES, THURN, LAN, DE

R081 Change of applicant/patentee

Owner name: OCE PRINTING SYSTEMS GMBH & CO. KG, DE

Free format text: FORMER OWNER: OCE PRINTING SYSTEMS GMBH, 85586 POING, DE

Effective date: 20130820

R082 Change of representative

Representative=s name: PATENTANWAELTE SCHAUMBURG, THOENES, THURN, LAN, DE

Effective date: 20130820

Representative=s name: SCHAUMBURG UND PARTNER PATENTANWAELTE MBB, DE

Effective date: 20130820

Representative=s name: SCHAUMBURG & PARTNER PATENTANWAELTE GBR, DE

Effective date: 20130820

Representative=s name: SCHAUMBURG & PARTNER PATENTANWAELTE MBB, DE

Effective date: 20130820

R082 Change of representative

Representative=s name: SCHAUMBURG UND PARTNER PATENTANWAELTE MBB, DE

Representative=s name: SCHAUMBURG & PARTNER PATENTANWAELTE GBR, DE

Representative=s name: SCHAUMBURG & PARTNER PATENTANWAELTE MBB, DE

R119 Application deemed withdrawn, or ip right lapsed, due to non-payment of renewal fee