Limbes

Original: http://inferno-os.com/inferno/limbo.html

Vita NuovaVita Nuova

 

Limbo est le langage de programmation application pour Inferno. Point de vue syntaxique similaire à C, il a plusieurs caractéristiques qui le rendent plus simple, plus sûr et encore plus puissant et mieux adaptée au développement de systèmes simultanés, distribués. Le compilateur Limbo génère le code architecture objet indépendant, qui est ensuite interprété par la Machine virtuelle Inferno ou compilé juste avant l’exécution pour améliorer les performances. Cela garantit que les applications de limbes sont complètement portables sur toutes les plateformes de Inferno.
Vie est rendue plus facile pour le programmeur avec des fonctionnalités telles que l’opération garbage collection automatique, compilation et runtime vérification de type et simple création de multiples processus (threads) et de la communication entre eux. Inferno est également livré avec un débogueur graphique, permettant à l’utilisateur à entrer dans le programme à tout moment et de naviguer dans l’état actuel.
Limbo a les types de données suivants :
  • octet (8 bits non signé)
  • int (32 bits signé)
  • gros (64-bit signé)
  • réel (64-bit virgule flottante)
  • liste
  • Tableau (avec découpage)
  • chaîne
  • Tuple (commandé la collection de types)
  • canal (pour la communication interprocessus)
  • ADT (“type de données abstrait”)
  • Pick (type d’union discriminé)
  • module
Exemples de programmes
Les exemples de programmes suivantes illustrent un programme simple qui prend un certain nombre de paramètres de ligne de commande et affiche chacun sur une nouvelle ligne avec une 1 seconde de l’écart entre les deux. Le deuxième exemple de programme utilise une approche multithread simple pour illustrer l’utilisation de base des canaux. (les numéros de ligne ont été insérés pour faciliter la consultation)
Programme 1

1:  implement Timer;

2:  include “sys.m”;
3:      sys: Sys;
4:  include “draw.m”;

5:  Timer: module {
6:      init: fn (nil: ref Draw->Context, argv: list of string);
7:  };

8:  init(nil: ref Draw->Context, argv: list of string)
9:  {
10:     sys = load Sys Sys->PATH;

11:     n := len argv;
12:     sys->print(“Command Line Parameters\n”);
13:     for (i := 0; i < n; i++) {
14:          sys->sleep(1000);
15:          sys->print(“%d: %s\n”, i, hd argv);
16:          argv = tl argv;
17:     }
18: }

Ligne 1 définit le nom du module (programme) avec les lignes 5-7 définissant l’interface, il présente au monde extérieur. La fonction init est requise dans l’interface d’un module à exécuter sur le réservoir Inferno comme un programme normal. Cette fonction est alors définie dans les lignes 8 à 18.
Lignes 2 et 4 comprennent les fichiers qui définissent les interfaces aux autres modules nécessitant une minuterie. Ligne 3 définit le sys de poignée module Sys d’être une variable globale.
Ligne 10 charge le module Sys (qui contient le sommeil et les fonctions d’impression utilisées sur les lignes 14 et 15) et commence une référence à celle-ci dans le sys variable globale
La coquille de l’Inferno transmet des paramètres de lignes de commande à un module par l’intermédiaire de la liste des chaîne variables argv dans la fonction init, qui fait partie de l’interface du module.
Ligne 11 attribue n le nombre d’éléments dans la liste, argv.
Ligne 13 indique au système de boucle n fois par le biais de lignes 14 à 16 qui attend la première pendant une seconde (le sys-> fonction sleep prend un argument de délai en millisecondes) et imprime ensuite le paramètre suivant dans la liste. Le programme parcourt la liste argv, à l’aide de la hd (tête) et les opérateurs tl (queue).
Programme 2
Dans cette version multi-thread du programme précédent, un minuterie démarrage du thread qui contrôle le taux auquel les paramètres de ligne de commande sont imprimées. Cela montre un canal utilisé pour la communication entre différents threads.

1:  implement Timer2;

2:  include “sys.m”;
3:      sys: Sys;
4:  include “draw.m”;

5:  Timer2: module {
6:      init: fn (nil: ref Draw->Context, argv: list of string);
7:  };

8:  init(nil: ref Draw->Context, argv: list of string)
9:  {
10:     sys = load Sys Sys->PATH;

11:     sync := chan of int;
12:     n := len argv;
13:     spawn timer(sync, n);

14:     sys->print(“Command Line Parameters\n”);
15:     for (i := 0; i < n; i++) {
16:         <-sync;
17:         sys->print(“%d: %s\n”, i, hd argv);
18:         argv = tl argv;
19:     }
20: }

21: timer(sync: chan of int, n: int)
22: {
23:     for (i := 0; i < n; i++) {
24:         sys->sleep(1000);
25:         sync <-= 1;
27:     }
26: }

Les 10 premières lignes remplissent la même fonction que dans le premier programme, pour définir et charger des modules requis.
Ligne 11 définit un canal, sync qui sera utilisé pour communiquer entre les différents threads (processus), le type de canal définissant les données qui peuvent être transmises à ce sujet par exemple un chan d’int peut être utilisé pour transmettre des entiers.
Ligne 13 commence le thread de minuterie à l’aide de la commande spawn. Dès lors, la fonction init et la fonction de minuterie seront déroulera simultanément dans des threads séparés.

 

Le programme entre maintenant dans une boucle de la même manière que le programme précédent. Cependant, au lieu d’utiliser sys-> sommeil à attendre une seconde, il attend une valeur à être envoyé sur le canal de synchronisation. La valeur peut être assignée à une variable à l’aide
variablename := <-sync;
mais comme la valeur n’est pas utilisée, la cession peut être omise.
Dans le fil de la minuterie, l’instruction loop tout d’abord fait une pause d’une seconde (ligne 24), puis envoie la valeur « 1 » vers le bas de la chaîne de synchronisation (ligne 25). Une fois que le thread a effectué les n fois de boucle, il se fermera.
Canaux avancée
C’est juste un exemple simple de l’utilisation des canaux de communication et de synchronisation entre des threads différents. Fonctionnalités avancées telles que l’écoute sur plusieurs canaux, traversant les types abstraits de données (y compris les canaux) canaux et en utilisant les canaux mis en mémoire tampon peuvent être utilisées dans le cadre de l’environnement simultanée sophistiqué fourni par Limbo.

Comments are closed.