X10, eine typsichere, parallele und objektorientierte Sprache

Projektwebseiteist eine von IBM entwickelte neue Programmiersprache auf Basis von Java und C++. Sie bietet vor allem für parallel laufende Anwendungen zahlreiche neue Sprachkonstrukte, die ansonsten nur unhandlich mit Java und Co. zu lösen wären. Dabei behält sie sich die Vorteile einer stark typisierten und objektorientierten Sprache wie Java bei.

Im Endeffekt bildet der X10-Compiler den geschrieben Code in Java oder C++ Code ab. Dies geschieht jedoch transparent und ist für den User (zumindest zu Beginn) nicht so wichtig. Erst bei möglichen Optimierungen durch den Compiler wird dies relevant, dann muss man sich zwischen der Java oder C++ Abbildung entscheiden. Ansonsten bietet die Sprache aber einen sehr schnellen Einstieg, sofern man etwas Java/C++ Vorkenntnisse besitzt. Auch die parallele Programmierung erweist sich als relativ komfortabel, sofern man einige Fallstricke kennt und umgeht.

Beispiel „Hello World“:
Das klassische Beispiel schlechthin, wer Java kennt wird sich daran erinnert fühlen:

class HelloWorld {
 public static def main(Array[String]) {
  Console.OUT.println("Hello World!" );
 }
}

Beispiel „paralleles Hello World“:
Ebenso klassisch, jedoch mit einem Fallstrick:

import x10.io.Console;
public class ConcHello1 {
  public static def main(argv:Rail[String]!) {
    async Console.OUT.println("Hello, World");
    async Console.OUT.println("Bore Da, Byd");
    async Console.OUT.println("Bonjour, Monde");
  }
}

Die Ausgabe dieser Methode sieht leider so aus:

BHelonlo,j oWuorr,l dM
onde
Bore Da, Byd

Warum? Weil die drei Ausgabebefehle zu 100% parallel laufen, das heißt sie schreiben alle drauf los, ohne auf den anderen zu achten. Dabei entsteht dann so ein Buchstabensalat. Möchte man die Ausgabe korrekt zu Gesicht bekommen, muss man dafür sorgen, dass die Threads untereinander abgestimmt ablaufen:

public class ConcHello2 {
  public static def main(argv:Rail[String]!) {
    val buffer = Rail.make[String](1);
    buffer(0) = "";
    async atomic buffer(0) = buffer(0) + "Hello, World\n";
    async atomic buffer(0) = buffer(0) + "Bore Da, Byd\n";
    async atomic buffer(0) = buffer(0) + "Bonjour, Monde\n";
    x10.io.Console.OUT.println(buffer(0));
  }
}

Durch das hinzugefügte Schlüsselwort atomic, laufen die einzelnen Texte nun voneinander getrennt. Im Puffer werden diese dann zwischengespeichert und anschließend ausgegeben. Jetzt sieht die Ausgabe schon wesentlich besser aus:

Bonjour, Monde
Bore Da, Byd
Hello, World

Die Reihenfolge ist dabei logischerweise nicht vorhersagbar, jenachdem welcher Thread schneller ist…
Jetzt kann es aber noch ein weiteres Problem geben, was man auf den ersten Blick vielleicht gar nicht sehen kann. Es kann nämlich auch passieren, das die Ausgabe wie folgt aussieht:

Bonjour, Monde

Warum das? Eigentlich auch relativ leicht zu erklären: Da das Programm an keiner Stelle auf die Pufferbefüllung wartet, kann es sein, das zu früh an die Stelle der Ausgabe gesprungen wird, die Ausgabe erfolgt dann nur mit einem Teil des gefüllten Puffers, da die beiden anderen Threads noch gar nicht fertig sind. Lösung? Einfach einen finish-Block um die async-Konstrukte setzen, damit wartet das Programm dann auf deren Beendigung:

public class ConcHello4 {
  public static def main(argv:Rail[String]!) {
    val buffer = Rail.make[String](1);
    buffer(0) = "";
    finish{
      async atomic buffer(0) = buffer(0) + "Hello, World\n";
      async atomic buffer(0) = buffer(0) + "Bore Da, Byd\n";
      async atomic buffer(0) = buffer(0) + "Bonjour, Monde\n ";
    }
    x10.io.Console.OUT.println(buffer(0));
  }
}

Und siehe da, die Ausgabe lautet korrekt:

Hello, World
Bonjour, Monde
Bore Da, Byd

Ich hoffe ich konnte euch einen kleinen Einblick in die Welt von X10 geben, wer mehr erfahren möchte ist auf der Projektwebseite gut aufgehoben, dort gibt es zahlreiche Tutorials etc.

2 Gedanken zu „X10, eine typsichere, parallele und objektorientierte Sprache

  • 30. November 2010 um 22:21
    Permalink

    Du hast mir damit das Leben gerettet -musste noch eine Arbeit vollenden, genau an diesem Stück Code denke ich schon eine Weile rum. Das ganze zu lösen wäre komplex gewesen -so war es kinderleicht^^ Guter Blog, weiterso ;)

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.