Geteilte Zeit: Time-Sharing

In den im vorhergehenden Kapitel vorgestellten Einsatzszenarien etwa des RAMAC-Computers und des LGP-30 überwogen die Vorteile der Echtzeitverarbeitung die Nachteile eines nicht vollständig ausgelasteten und zudem recht langsamen Computers. Die Echtzeitnutzung kam hier deswegen infrage, weil wenige Nutzer den Rechner gebrauchten und die mit dem Rechner zu lösenden Probleme übersichtlich waren. Es gab somit keinen Bedarf an besonders gut ausgestatteten, schnellen Rechnern. Wollten jedoch viele Nutzer Rechendienste beanspruchen und brachten diese Nutzer eine Vielzahl verschiedener Programme mit, deren Erledigung eine gut ausgebaute Rechenanlage voraussetzte, kamen die genannten Geräte und eine Bedienung des Computers durch den Nutzer selbst nicht mehr infrage. Ärgerlicherweise war aber gerade für diese Nutzer, die ja häufig neue, umfangreiche Programme für komplexe Berechnungen erstellen mussten, die Batch-Betriebsart besonders lästig, denn sie machte das Programmieren sehr umständlich, zeitaufwändig und fehlerträchtig. Programme mussten handcodiert und abgelocht werden und die Rückmeldung zu nahezu unausweichlichen Programmierfehlern kamen erst nach Stunden oder gar Tagen. Den Ausweg aus der Batch-Nutzung für große, leistungsfähige Rechner brachte die Erfindung des „Time-Sharing“. Erste konzeptuelle und theoretische Vorarbeiten hierzu begannen bereits in den 1950er Jahren, die ersten nicht-rein-experimentellen Systeme wurden jedoch erst Mitte der 1960er in Betrieb genommen.

Fernschreiber ASR-33 – Bild: AlisonW (CC BY-SA 3.0)
Fernschreiber ASR-33 – Bild: AlisonW (CC BY-SA 3.0)

Beim Batch-Computing wurde eine hohe Auslastung des Computers dadurch erreicht, dass ein Computer sich nahezu nie im Wartezustand befand, sondern immer ein Programm vorlag, an dem gerechnet wurde. Auch beim Time-Sharing war es das Ziel, den Computer möglichst gut auszulasten. Das wurde allerdings nicht mehr dadurch gewährleistet, dass dem Computer in hoher Taktung Jobs zugeführt wurden, die dann nacheinander abgearbeitet werden konnten. Beim Time-Sharing teilten sich vielmehr die Programme vieler Nutzer die Rechenzeit des Computers. Sie liefen quasi gleichzeitig, bzw. so schnell abwechselnd, dass es so erschien, als sei dies der Fall. Mit dem Time-Sharing kam der Nutzer nun auch mit dem Rechner selbst in Kontakt. Dies geschah allerdings nicht direkt im Rechnerraum, der nach wie vor tabu war, sondern mittels sogenannter „Terminals“, die mit dem Rechner verbunden waren. Typische Terminals für frühe Time-Sharing-Systeme waren einfache Fernschreiber wie der rechts abgebildete. Nutzer konnten an Fernschreibern Eingaben machen und bekamen Ausgaben ihres Programms während des Programmablaufs direkt ausgedruckt. Ein Nutzer eines Time-Sharing-Systems musste an seinem Fernschreiber nicht warten, bis ein Programm eines anderen Nutzers zum Ende gekommen war, denn Time-Sharing-Systeme arbeiteten die Programme der Nutzer ja im Rundumverfahren ab. Es wurde in so schneller Folge zwischen den Programmen hin- und hergewechselt, dass für jeden einzelnen Nutzer die Illusion entstand, den Computer ganz für sich zu haben.

Das Nutzererlebnis eines Time-Sharing-Systems mit Fernschreiber war fundamental anders als das der Nutzung eines Computers im Batch-Betrieb. Statt Lochkartenstapel abzugeben und Stunden später Lochkarten und Ausdrucke zurückzuerhalten, wurden nun Befehle per Texteingabe über den Fernschreiber an den Computer gegeben. Dieser reagierte wiederum durch die Ausgabe von Texten, die vom Fernschreiber auf Endlospapier gedruckt wurden. Statt wie bisher stundenlang auf Ergebnisse zu warten, erschienen die Ergebnisse innerhalb von Minuten oder gar wenigen Sekunden. Die Arbeitsweise ist der des SABRE-Systems ganz ähnlich, bei der ja auch Terminals mit einem Computer verbunden wurden und Eingaben gemacht werden konnten, auf die der Zentralrechner umgehend antwortete. Beim SABRE-System gab es jedoch nur ein einziges laufendes Programm, das alle Terminals mit der gleichen Funktionalität bediente. Time-Sharing-Systeme hingegen waren so ausgelegt, dass sie die volle Flexibilität der individuellen Programmierung verfügbar machten. Jeder Computernutzer konnte seine eigenen Programme erstellen, auf dem Time-Sharing-System laufen lassen und zeitnah ein Ergebnis erhalten.

Für die Performance und Auslastung einer Rechenanlage hatte Time-Sharing natürlich seinen Preis:

Arbeitsspeicherbedarf: Da sich viele Programme gleichzeitig im Speicher befanden und zusätzliche Daten für die Verwaltung der angemeldeten Nutzer und der laufenden Programme notwendig waren, mussten Time-Sharing-Systeme mit mehr Arbeitsspeicher ausgestattet werden als für die Durchführung der gleichen Berechnungen im Batch-Betrieb notwendig gewesen wäre.

Performance: Die Organisation des Time-Sharing-Betriebs selbst verursachte einen sogenannten „Overhead“. Wenn zwanzig Nutzer gleichzeitig angemeldet waren und ein Programm laufen ließen, dann dauerte es insgesamt länger, als wenn man die zwanzig Programme hintereinander ablaufen lassen hätte, denn für das Wechseln zwischen den Programmen ging stetig Rechenzeit verloren. Diese verschenkte Zeit wurde umso größer, je mehr Nutzer das System benutzten. Die Verzögerung in der Bearbeitung war aber in der Regel zu verschmerzen, denn da das für den Nutzer ja so besonders unpraktische Job-Handling, das Ablochen und das lange Warten auf ein Ergebnis entfielen, wurde es für jeden einzelnen Nutzer trotz insgesamt langsamerer Verarbeitung doch signifikant schneller.

Auslastung: Der Batch-Betrieb sorgte für eine gleichmäßige Auslastung des Rechners auch in Zeiten, in denen wenige neue Jobs eingingen. Während der Stoßzeiten häuften sich die Jobs und landeten in einer Warteschlange. Diese Warteschlange konnte in Zeiten mit wenig Andrang abgearbeitet werden. Beim Time-Sharing hingegen wurde die Bearbeitung sehr langsam, wenn viele Nutzer das System nutzen, während Rechenzeit im großen Stile verschwendet wurde, wenn nur wenige Nutzer Programme laufen ließen. Um dennoch für eine gute Auslastung zu sorgen, wurden Time-Sharing- und Batch-Betrieb häufig kombiniert. Das Betriebssystem des Rechners bediente Nutzer an ihren Fernschreibern im interaktiven Betrieb, arbeitete aber gleichzeitig auch klassische Jobs ab. In Zeiten, in denen wenig interaktive Nutzung zu verzeichnen war, konnte dem Batch-Betrieb entsprechend mehr Priorität eingeräumt werden. Manche Time-Sharing-Systeme verbanden die beiden Betriebsarten sogar noch geschickter. Sie erlaubten etwa den Nutzern das Bearbeiten und Testen ihres Programms im Echtzeitbetrieb und ermöglichten es dann, die Ausführung des Programms, eventuell mit einer großen Datenmenge, in eine Batch-Warteschlange einreihen zu lassen, die dann bei Gelegenheit abgearbeitet wurde. M. V. Wilkes beschreibt dies16 für das Cambridge Time-Sharing System. Dort konnten Programmdateien per Editor vorbereitet werden und dann durch die Eingabe von RUNJOB und dem Dateinamen in eine klassische Job-Queue eingereiht werden. Die Ausgaben dieser Programme wurden entweder klassisch ausgedruckt oder aber wiederum als Datei zur Verfügung gestellt.

Mit dem Time-Sharing änderte sich die Art und Weise, wie Programme erzeugt und bearbeitet wurden. Es war nun nicht mehr nötig, diese Aufgabe auf Papier zu erledigen und das Programm dann manuell abzulochen. Der Computer konnte nun endlich selbst zum Programmieren genutzt werden. Damit das ging, brauchte es aber ein spezielles Programm zum Bearbeiten des Programmcodes, also einen Editor. Diesem Editor werden wir uns gleich widmen. Vorher sollten Sie sich jedoch einige Konsequenzen des Time-Sharings für die Nutzungsschnittstelle bewusst machen.

Virtuelle Objekte

Mit dem Aufkommen von Time-Sharing ging auch der Übergang von Konsolen zur Steuerung und Überwachung der Maschine zu für den Nutzer geschaffenen Nutzungsschnittstellen einher. Bisherige Computer brauchten keine Schnittstelle für den Nutzer des Rechners, denn Rechner und Nutzer kamen schon physisch gar nicht miteinander in Kontakt. Das wurde nun anders: Ein Nutzer, der am Fernschreiber saß, stand direkt mit dem Computer in Verbindung, auf dem seine Programme liefen. Er musste also eine Möglichkeit haben, die Programme auszuwählen und zu starten, sie zu erstellen oder sie gegebenenfalls zu löschen. Hierfür reichte es nicht, einfach eine textuelle Umsetzung dessen bereitzustellen, was bisher mit den Operator-Konsolen möglich war. Diese Konsolen waren sehr komplex und boten direkten Zugriff auf die Hardware des Rechners, auf interne Zustände und Speicherregister. Ein Nutzer an einem Fernschreiber war aber an Maschinenzuständen und Speicheradressierungen nicht interessiert, sondern benötigte eine Schnittstelle, die sich auf die von ihm verarbeiteten Daten und Programme bezog. Die vom Computer bereitgestellte Schnittstelle musste dem Nutzer die Programme und die Daten als etwas anbieten, auf das er sich beziehen konnte. Das begann schon bei dem Grundsystem des Time-Sharing-Systems, dem Kommando-Interpreter, mit dem etwa Programme gestartet werden konnten.

Eines der ersten Time-Sharing-Systeme, das nicht nur rein experimentell war, war das Dartmouth Time Sharing System (DTSS) am Dartmouth College in den USA. Es wurde 1964 in Betrieb genommen. Meldete man sich beim System an, musste man sich zunächst mit einer Nutzernummer identifizieren. War dies geschehen, konnte man entweder direkt mit der Programmierung eines Programms beginnen – dazu später mehr – oder aber auch bereits existierende Programme verwalten. Dazu stand eine Reihe von Befehlen zur Verfügung:

  • LIST gab das Listing des aktuell geladenen Programms aus.
  • NEW erzeugte ein neues Programm. Ein Programmname wurde nach der Eingabe von NEW abgefragt.
  • OLD ermöglichte, ein früheres Programm wieder zu laden. Nach Eingabe von OLD wurde der Programmname des gespeicherten Programms abgefragt.
  • SAVE speicherte das Programm unter dem aktuellen Programmnamen ab.
  • UNSAVE löschte das Programm mit dem aktuellen Programmnamen.
  • SCRATCH löschte das Programm, behielt aber den Programmnamen bei. Der Nutzer konnte also von vorne beginnen.
  • CATALOG gab eine Liste aller für den angemeldeten Nutzer gespeicherten Programme aus.

Worauf bezogen sich diese Befehle? Es ging nun nicht mehr wie bei klassischer Programmierung um Register, Speicherstellen oder Sektoren auf Massenspeichern. Die Befehle bezogen sich zwar auf Programme, aber nicht im Sinne der einzelnen Anweisungen einer Programmiersprache, sondern auf Programme als Ganzes, auf etwas, das der Nutzer mit einem Namen ansprechen konnte. Ich nenne derartige Entitäten, auf die sich ein Nutzer in einer interaktiven Nutzungsschnittstelle beziehen kann und die von dieser Schnittstelle für den Nutzer erzeugt und zugreifbar gemacht werden, virtuelle Objekte.

Das Wort „virtuell“ wird in der deutschen Wikipedia meiner Meinung nach sehr bestechend definiert:

Virtualität ist die Eigenschaft einer Sache, nicht in der Form zu existieren, in der sie zu existieren scheint, aber in ihrem Wesen oder ihrer Wirkung einer in dieser Form existierenden Sache zu gleichen. Virtualität meint also eine gedachte Entität, die in ihrer Funktionalität oder Wirkung vorhanden ist.

Das, was ich hier „virtuelle Objekte“ nenne, existiert nicht realweltlich als Objekt im Sinne eines Gegenstandes. Für den Umgang mit dem Computer haben die virtuellen Objekte aber die Eigenschaften von tatsächlichen Objekten. Man kann sich also auf sie beziehen, sie erzeugen, vernichten und natürlich manipulieren.

In diesem Zusammenhang den Begriff „Objekt“ zu verwenden, ist übrigens meine Wortwahl entsprechend der Perspektive, die ich Ihnen in diesem Buch darlegen will. Auch in älteren Beschreibungen und Anleitungen von Computersystemen und Programmiersprachen findet man den Objekt-Begriff mitunter in dieser Verwendung. Mit dem Aufkommen der sogenannten „objektorientierten Programmierung“ wurde der Objektbegriff in der Informatik mit einem gewissen Programmierparadigma belegt. Der Begriff wurde regelrecht annektiert. Es geht mir hier aber nicht um die Programmierung, sondern auf die von der Nutzungsschnittstelle erzeugte Welt für den Nutzer. Das, was ich hier „Objekt“ nenne, ist für den Nutzer ein ansprechbares und manipulierbares Gebilde. Wie ein Programmierer hinter den Kulissen dieses Objekt realisiert, ob es auch da etwas gibt, was das Objekt als eine Einheit erscheinen lässt, oder ob es sich um eine Ansammlung von Variablen oder gar Datenströmen handelt, ist aus der Perspektive der Nutzungsschnittstelle nicht von Belang.

Die Time-Sharing-Applikation schlechthin: Der Editor

Die Möglichkeit, Programme unter direkter Nutzung des Computers zu bearbeiten und so die Misslichkeiten der Programmierung mit Lochkarten und Lochstreifen hinter sich zu lassen, war eine der Haupt-Triebkräfte hinter der Entwicklung von Time-Sharing-Systemen. Dass mit diesen Systemen dann auch Programme möglich waren, die interaktiv gesteuert werden können, wurde zwar gesehen, stand aber nicht unbedingt im Vordergrund und war, wie Sie gleich sehen werden, auch nicht in jedem Time-Sharing-System von Beginn an möglich. Haupt-Anwendung war in der Regel die Editor-Funktionalität.

Wenn Sie sich unter einem Editor ein Programm vorstellen, dass in etwa so aussieht wie ein Texteditor unter Windows oder MacOS oder gar wie eine moderne Programmierumgebung, dann haben Sie eine falsche Vorstellung. Die Bedienung eines Editors der damaligen Zeit war ganz anders als die Verwendung moderner Editoren. Begründet liegt dies in den Eigenschaften des Fernschreibers als Ein- und Ausgabegerät, die nicht recht zur Aufgabe eines Editors passten. Da Fernschreiber ganz analog etwas auf ein Blatt schrieben, kann man mit einem Fernschreiber wie mit einer Schreibmaschine immer nur etwas hinzufügen, also etwas Neues dazuschreiben. Die Aufgabe eines Editors ist es jedoch, einen im Computer befindlichen Text, etwa einen Programm-Quelltext, zu bearbeiten, also zu ändern. Was schon auf einem Blatt Papier steht, kann man aber nicht ändern. Es gab bei einem Fernschreiber kein Löschen und kein Backspace im heutigen Sinne. Fernschreiber wie der zuvor abgebildete ASR-33 verfügten zwar über eine „Rubout“-Taste, die gedrückt werden konnte, um durchzugeben, dass das vorher gesendete Zeichen „ausgewischt“ werden sollte. Natürlich wurde aber auch hier das vorherige Zeichen nicht vom Papier des Empfängers getilgt. Wurde einem Computer ein solches Zeichen geschickt, löschte er die Eingabe intern und schickte zur Bestätigung ein neues Zeichen zurück – häufig das Dollarzeichen – um darzustellen, dass die Eingabe akzeptiert wurde. Diese Art der Ein- und Ausgabe mag für das Löschen eines gerade eingegebenen falschen Zeichens noch hinreichend sein, stieß aber spätestens beim Versuch, Text zwischen vorhandene Worte einzufügen, an ihre Grenzen. Komplexere Aufgaben wie das Einfügen von Text konnten nur durchgeführt werden, indem dem Editor Befehle eingegeben wurden, die beschrieben, wie der Text angepasst werden konnte.

Wenn Sie Zugriff auf ein Linux- oder Unix-System (inklusive MacOS) haben, können Sie diese Funktionsweise früher Editoren noch heute nachvollziehen. Der in diesen Systemen verfügbare Zeileneditor „ed“ stammt aus der Anfangszeit des Betriebssystems Unix von Anfang der 1970er Jahre, aus einer Zeit also, als viele Computer noch per Fernschreiber bedient wurden.

Wird der Editor durch die Eingabe von ed in der Kommandozeile gestartet, passiert zunächst einmal gar nichts, außer dass ein Zeilenvorschub ausgelöst wird oder im modernen Bildschirm-Terminal der Cursor (die Schreibmarke) in die nächste Zeile wandert. Schreiben Sie nun nacheinander H und P jeweils gefolgt von Enter. Diese beiden Befehle sorgen dafür, dass Meldungen ausgegeben werden, wenn Fehler auftreten, und dass mit einem * angezeigt wird, wenn Sie eine Befehlseingabe machen können. Als ersten Schritt laden Sie eine Datei. Nehmen wir an, dass eine Datei „textfile.txt“ bereits existiert. Mit der Eingabe von r textfile.txt wird, nach der Bestätigung mit Enter, die Datei eingelesen. Der Editor antwortet mit der Anzahl der gelesenen Bytes, in unserem Beispiel 86. Da die Datei nicht groß ist, können Sie sie in ganzer Länge ausgeben. Dies geschieht durch eine Eingabe des Befehls ,l (hierbei handelt es sich um ein kleines L und nicht um die Zahl 1).

$ed
H
P
*r textfile.txt
86
*,l
This is the heading.$
The text starts hree. There may be many important things to say.$

Wie Sie sehen, handelt es sich hier um einen einfachen Text bestehend aus zwei Zeilen. Das Dollarzeichen steht jeweils für das Zeilenende. Sie können diesen Text nun bearbeiten, indem Sie Befehle eingeben. Im Beispiel werden wir zum einen unterhalb der Überschrift eine Zeile mit Plus-Zeichen einfügen, um sie besser abzusetzen, und zum anderen das Wort „hree“, wohl ein Tippfehler, durch das korrekte Wort „here“ ersetzen.

Um die Pluszeichen einzugeben, müssen Sie dem Editor mitteilen, dass Sie in Zeile 2 etwas einfügen wollen. Dies geschieht durch den Befehl 2i. Nun können Sie den neuen Text eingeben. Um die Eingabe abzuschließen, schreiben Sie einen einzelnen Punkt in eine Zeile und beenden Sie mit Enter:

*2i
+++++++++++++++++++++
.

Die ehemalige Zeile 2 müsste durch das Einfügen einer weiteren Zeile jetzt zur Zeile 3 geworden sein. Sie können das überprüfen, indem Sie die Zeile 3 mit dem Befehl ,3 ausgeben lassen.

*,3
The text starts hree. There may be many important things to say.$ 

Nun geben Sie einen Befehl ein, um in Zeile 3 das erste Vorkommen von „hree“ durch „here“ zu ersetzen und geben anschließend den kompletten berichtigten Text mit ,l nochmals aus.

*3s/hree/here/
*,l
This is the heading.$
+++++++++++++++++++++$
The text starts here. There may be many important things to say.$

Hiermit sind die beabsichtigten Änderungen abgeschlossen. Abschließend können Sie den verbesserten Text mit w besser.txt als „besser.txt“ abspeichern. Der Editor quittiert das wiederum durch die Angabe der geschriebenen Bytes. Die Eingabe des Befehls q beendet dann den Editor.

*w besser.txt
108
*q 

Konnten Sie beim Nachvollziehen dieses Beispiels das Hin und Her an einem Fernschreiber nachempfinden? Das Bearbeiten eines Textes ist auf diese Art und Weise sehr umständlich, denn man bearbeitet den Text nur indirekt. Der Text liegt im Computer zwar als bearbeitbares Objekt vor, aber man kann ihn nicht als Text sehen und an Ort und Stelle bearbeiten. Man muss stattdessen Befehle zur Bearbeitung geben und den aktuellen Zustand des Textes immer wieder ganz oder in Ausschnitten anfragen. Man kann diese Arbeitsweise in etwa damit vergleichen, als würde man jemanden anrufen, der einen Text vor sich liegen hat und diesen immer in Teilen durchgibt. Dieser Person könnten sie nun die Änderungen, die Sie machen wollen, durchgeben und dann immer wieder erfragen, wie jetzt der aktuelle Zustand des Texts ist.

Virtuelle Objekte: Interaktive Objektmanipulation

Im Editor erscheint der Text nicht etwa als Bitstrom oder als lange Zeichenkette, die er ja faktisch ist. Würde „ed“ kein Konzept von Zeilen als ansprechbare Objekte haben, wäre es noch viel umständlicher, den Editor zu nutzen, denn dann könnte man sich nicht auf Zeilen beziehen, sondern müsste Bytes innerhalb eines Datenstroms adressieren, sich also noch viel stärker auf die Ebene der Rechnerarchitektur hinunterbegeben. „Ed“ erzeugt hingegen durch seine Nutzungsschnittstelle für den Nutzer verstehbare, adressierbare, wahrnehmbar-machbare und manipulierbare Objekte. Jede sinnvolle Schnittstelle für Echtzeitsysteme erzeugt derartige virtuelle Objekte, auf die sich der Nutzer beziehen kann. Bei „ed“ waren es hier Zeilen und Zeichen. Auf der Ebene des Kontrollprogramms, des Kommandozeilen-Interpreters, sind es Programme und Dateien. Verwenden Sie ein Programm zur Verwaltung von Terminen, sind es Kalendereinträge. In all diesen Fällen beziehen Sie sich auf ein Objekt der Welt der Nutzungsschnittstelle statt auf Adressbereiche und Maschinenoperationen. Es handelt sich in all diesen Fällen, so einfach die Umsetzung der Nutzungsschnittstellen noch sein mag, um Nutzungsschnittstellen, die durch den Computer erzeugt werden, anstatt nur die Schnittstelle für den Computer zu sein. Programme für den Echtzeitbetrieb erzeugen sowohl die Bedienelemente, mit Hilfe derer sie bedient werden können, als auch die Objekte, wegen derer die Software überhaupt existiert. Was auf der anderen Seite der Nutzungsschnittstelle steckt, also die technische Implementierung der Software, ist für den Nutzer – zumindest in dieser Sichtweise – nicht von Belang und bleibt für ihn unsichtbar.

Das folgende Bild zeigt Studenten des Dartmouth College samt dem Mathematikprofessor John G. Kemeny. Sie sitzen rund um eine Reihe von Fernschreibern, die mit einem zentralen Computer verbunden sind. Am Dartmouth College wurde eines der ersten Time-Sharing-Betriebssysteme in Betrieb genommen. Von diesem Dartmouth Time-Sharing System war oben bereits einmal die Rede. Das System ging am 1. Mai 1964 in Betrieb.

BASIC-Miterfinder John G. Kemeny mit einigen Studenten an mit dem DTSS verbundenen Fernschreibern – Bild mit freundlicher Genehmigung der Dartmouth College Library
BASIC-Miterfinder John G. Kemeny mit einigen Studenten an mit dem DTSS verbundenen Fernschreibern – Bild mit freundlicher Genehmigung der Dartmouth College Library

Für das System wurde von besagtem John G. Kemeny zusammen mit Thomas E. Kurtz und Mary Kenneth Keller eine Programmiersprache namens BASIC (Beginner’s All-purpose Symbolic Instruction Code) entwickelt. BASIC zielte, wie der Name es sagt, auf den Einsatz als Anfängersprache, gerade in Bildungsinstitutionen, ab. Ziel war es, nicht nur angehenden Technikern und Ingenieuren, sondern allen Studierenden und Mitarbeitern des College und darüber hinaus das Programmieren zu ermöglichen. Die Sprache wurde etwa fünfzehn Jahre später zu einer der weitestverbreiteten Programmiersprachen. Quasi alle Heim- und Personal-Computer der 1980er Jahre waren mit einem BASIC-Interpreter ausgestattet. Betrachten Sie einmal das folgende kleine Programm, das die Zahlen von 1 bis 10 ausgibt.

10 FOR I=1 TO 10
20 PRINT I
30 NEXT I
40 END

Wie Sie sehen, beginnt jede Zeile mit einer Zeilennummer. Die Zeilennummern gehören fest zur Sprache BASIC. Sie dienen zwei ganz unterschiedlichen Funktionen. Rein funktional werden die Zeilennummern gebraucht, um im Programm springen zu können. Ein GO TO 100 (in späteren BASIC-Dialekten meist ohne Leerzeichen, also GOTO 100, geschrieben) etwa setzt den Programmablauf in Zeile 100 fort. Die Zeilennummern haben aber auch eine Funktion in der Nutzungsschnittstelle, erlauben sie es doch, Zeilen neu zu definieren und neue Zeilen zwischen den schon vorhandenen einzufügen. Wollen Sie das obige Programm etwa so abändern, dass es nicht die Zahlen von 1 bis 10, sondern von 2 bis 20 in Zweierschritten ausgibt, können Sie Zeile 20 einfach neu definieren:

20 PRINT 2*I

Wenn Sie geschickterweise zwischen den Zeilennummern größere Abstände gelassen haben, können Sie auch leicht Zeilen zwischenfügen, indem Sie einfach Zeilennummern zwischen den vorhandenen verwenden, also etwa:

15 PRINT "EINE ZAHL",
35 PRINT "FERTIG!"

Die erste Version des Dartmouth BASIC verfügte zwar durch das DTSS über einen interaktiven Editor, man konnte mit der Sprache allerdings keine Programme schreiben, die selbst interaktiv waren, denn es gab keine Möglichkeit, den Nutzer zu Eingaben aufzufordern. Alle Eingabedaten mussten, wie bei der Batch-Verarbeitung, im Vorfeld bekannt sein. BASIC fehlte auch eine Möglichkeit, Daten aus Dateien zu lesen, denn DTSS unterstützte keinerlei Daten-Dateien. Alle Daten mussten also im Programm selbst angegeben werden. Im folgenden Beispiel sehen Sie, dass dabei die frühere Batch-Denkweise mit Programm-Lochkarten und Daten-Lochkarten durchaus noch durchscheint.

100 PRINT "RECHNUNG"
200 PRINT
300 PRINT "MENGE","PREIS"
400 PRINT "------------------------------------"
500 LET SUMME=0
600 READ MENGE
700 IF MENGE=0 THEN 1100
800 READ PREIS
850 PRINT MENGE, PREIS
900 LET SUMME = SUMME + MENGE * PREIS
1000 GO TO 600
1100 PRINT
1200 PRINT "SUMME:"; SUMME 
1300 REM
1400 REM RECHNUNGSDATEN
1500 REM
1600 DATA 5,1.90
1700 DATA 1,2.70
1800 DATA 2,1.39
1900 DATA 7,0.99
2000 DATA 0
9000 END

Dieses Programm gibt eine Rechnung aus. Hierzu werden in Zeile 600 und 800 Daten eingelesen. Diese Daten sind im unteren Bereich des Programms ab Zeile 1600 angegeben. Der Ort dieser DATA-Zeilen ist ohne Belang. Sie könnten genauso gut auch am Anfang des Programms oder verteilt im Programm auftauchen. Die Daten wurden hier, dem Programm entsprechend, in Zweiergruppen aus einer Menge und einem Preis angegeben. Für BASIC ist diese Gruppierung allerdings unwichtig. Nur die Reihenfolge entscheidet. Es könnten etwa alle Daten mit Komma getrennt innerhalb einer Zeile definiert werden. In Zeile 2000 steht eine 0 als Datum. Diese Null wird in der Programmlogik als Indikator dafür genutzt, dass keine weiteren Daten folgen. Wird diese Null in Zeile 600 gelesen, springt das Programm von Zeile 700 in Zeile 1100 und setzt mit der Ausgabe der Gesamtsumme fort. Würde man die Null weglassen, würde das Programm versuchen, weiter Daten einzulesen und mit einer Fehlermeldung abbrechen. Startete man das Programm, erhielt man eine Ausgabe folgender Art:

USER NO. 163405    PROBLEM NAME: RECHNUNG   6 SEPT. 1963    TIME: 19:34

RECHNUNG

MENGE              PREIS
------------------------------------
5                  1.9
1                  2.7
2                  1.39
7                  0.99

SUMME: 21.91


TIME:   1 SECS.

BASIC wurde – unter anderem von Studenten des College – intensiv weiterentwickelt. In der dritten Iteration im Jahre 1966 wurde der INPUT-Befehl eingeführt, der nun interaktive Programme ermöglichte. Wurde der Befehl ausgeführt, gab das System ein Fragezeichen aus. Der Nutzer konnte nun eine Eingabe machen. Mit einem Zeilenvorschub wurde die Eingabe beendet. Mit diesem INPUT-Befehl wurden nun Programme wie das folgende möglich:

100 PRINT "RATE EINE ZAHL ZWISCHEN 1 UND 100."
110 LET X = INT(100*RND(0)+1)
120 LET N = 0
150 PRINT "DEIN TIPP";
160 INPUT G
170 LET N = N+1
180 IF G = X THEN 400
190 IF G < X THEN 250
200 PRINT "ZU GROSS!"
210 GO TO 150
250 PRINT "ZU KLEIN!"
260 GO TO 150
400 PRINT "RICHTIG GERATEN!"
410 PRINT "DU HAST"; N; "ZUEGE GEBRAUCHT"
420 END

Bei diesem Programm handelt es sich um ein einfaches Spiel. Die Aufgabe des Spielers ist es, eine Zahl zwischen 1 und 100 zu erraten. Der Computer gibt nach jedem Raten an, ob die geratene Zahl zu groß oder zu klein ist, bis die Zahl schlussendlich geraten wird. An einigen Merkmalen dieses Listings sehen Sie, wie sehr BASIC ganz auf fernschreiberbasierte Time-Sharing-Systeme ausgelegt ist. Das beginnt bereits bei der Wahl der Worte für die Befehle. PRINT bedeutet nicht neutral „Schreiben“, sondern eben das, was ein Fernschreiber tut, nämlich Drucken. Der Befehl INPUT erzeugt eine für Fernschreiberbedienung typische Eingabemöglichkeit. Ein Hinweiszeichen wird ausgegeben, das dem Nutzer anzeigt, dass eine Eingabe erwartet wird. Der Computer verarbeitet vorhandene Eingaben auf Zeilenbasis. Der Zeilenvorschub wird also zur Freigabe der Eingabe. Ebenfalls gut optimiert ist die Funktionsweise des Editors. Programmteile können durch das Definieren neuer Zeilen und das Überschreiben bestehender Zeilen verändert werden. Einblick in das Programm kann ganz oder auch in Teilen durch den Befehl LIST genommen werden. Diese Art, das Programm zu verbessern und zu ergänzen, ist einer Bedienung per Fernschreiber und der mit ihm verbundenen Nachteile sehr angemessen. Das Problem bleibt, ähnlich wie bei „ed“ oben, dass man das Programm nur im Überblick sieht, wenn man es „auslistet“. Wenn man es dann bearbeitet, ist diese Änderung natürlich nicht im vorher gedruckten Listing zu sehen. Man muss als Programmierer den aktuellen Zustand des Programmcodes also im Kopf haben oder häufig neue Listings anfordern.

Was ist geblieben?

Das Time-Sharing-System DTSS ist von seinem Funktionsumfang her ziemlich eingeschränkt. Es stellt seinen Nutzern lediglich eine Programmierumgebung bereit. Neben BASIC konnte auch in den wissenschaftlichen Programmiersprachen ALGOL und FORTRAN mit dem System programmiert werden. Spätere Time-Sharing-Systeme, die im Laufe der Jahre entstanden, waren weit umfangreicher. Sie boten dem Nutzer Zugriff auf eine Vielzahl von Systemprogrammen, verfügten über ausgefeilte Editoren und Compiler für eine Vielzahl von Programmiersprachen. Hinzu kamen Verwaltungsfunktionen für die Nutzer des Systems. Für jeden Nutzer mussten eigene Bereiche für das Speichern von Programmen und Daten vorgesehen und vor dem Zugriff durch andere Nutzer geschützt werden. Time-Sharing-Systeme in großen Organisationen wie Universitäten verfügten zudem oft über Einrichtungen zu Rechenzeit- und Plattenplatzbeschränkung (sogenannte „Quotas“), um einen Betrieb mit vielen Nutzern gewährleisten zu können.

Was ist geblieben von den Time-Sharing-Systemen der frühen Zeit, die doch heute einigermaßen altertümlich wirken? Es mag Sie vielleicht wundern, aber tatsächlich können viele der Eigenheiten heutiger Betriebssysteme auf die frühen Time-Sharing-Systeme zurückgeführt werden. Es lassen sich hier sehr klare Entwicklungslinien erkennen. Großen Einfluss hatte zum Beispiel das ab 1963 entwickelte Multics (Multiplexed Information and Computing Service). Viele der Innovationen dieses Betriebssystems, etwa ein hierarchisches Dateisystem, fanden Eingang in das Betriebssystem UNIX, das beim amerikanischen Telefonmonopolisten AT&T ab 1969 entwickelt wurde. UNIX, ebenfalls ein Time-Sharing-System, hatte starken Einfluss auf das PC-Betriebssystem MS-DOS und damit auch auf Windows. Schlussendlich basiert das freie Betriebssystem Linux ebenfalls auf den Konzepten von UNIX.

Ein weiteres einflussreiches frühes Time-Sharing-System war das System TOPS-10 von 1967, das auf Großrechnern der Digital Equipment Corporation, kurz DEC, lief. Die für die damalige Zeit sehr benutzerfreundliche Arbeitsweise dieses Systems war Grundlage für das Betriebssystem OS/8 für die Minicomputer von DEC. Dieses OS/8 wiederum inspirierte Gary Kildall bei der Entwicklung des Betriebssystems CP/M, das auf frühen Microcomputern sehr große Verbreitung fand. CP/M wiederum war die Vorlage für Microsofts MS-DOS und MS-DOS blieb lange Zeit die technische Basis von Windows. Noch heute entspricht der Kommandozeilen-Interpreter von Windows, die „Eingabeaufforderung“, der Funktionsweise der MS-DOS-Kommandozeile. In dieser Eingabeaufforderung können Sie zum Auflisten von Dateien den Befehl dir eingeben. Diesen können Sie durch die ganze Kette über MS-DOS, CP/M, und OS/8 bis zu TOPS-10 zurückverfolgen.

Auch wenn Sie diese konkreten Befehle einmal außer Acht lassen, sind die Kommandozeilen heutiger Betriebssysteme Werkzeuge, die ihren Großvätern und Urgroßvätern aus der Time-Sharing-Ära sehr ähneln. Öffnen Sie doch einmal die Eingabeaufforderung von Windows oder ein Terminal unter MacOS oder Linux und probieren Sie einige Befehle aus. Bei dem ständigen Hin und Her zwischen der Eingabezeile und den Ausgaben des Systems können Sie mit etwas Fantasie noch regelrecht den Fernschreiber rattern hören…