2010-07-01 6 views
5

Longue histoire courte J'essaie de reproduire le problème du barbier endormi à Erlang.Liste des PID à Erlang

Dans ma solution j'ai décidé que pour tous les processus en attente je les mettrais dans une liste. Puis, une fois que les processus virent, j'éliminerais ce PID de la liste.

Malheureusement quand je l'appelle

length(myListOfPids). 

elle échoue, comme exemple:

length([<0.46.0>]). 
* 2: syntax error before: '<' 

est-il un moyen de stocker de PID pour que je puisse les rappeler et de les utiliser normalement? à savoir

PID ! message 

... juste au cas où il importe ici est l'erreur réelle que je reçois lors de l'exécution de mon programme:

=ERROR REPORT==== 1-Jul-2010::05:50:40 === 
Error in process <0.44.0> with exit value: 
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]} 

barber1 est mon module, waitingRoom est la fonction qui permet de suivre les processus qui sont en attente

Répondre

6

Entrer des Pids en les tapant ne fonctionne pas non plus pour moi. Est-ce le seul problème?

Avec code:

-module(test). 
-export([loop/0]). 

loop() -> 
    receive 
     {hello} -> 
      io:format("Hello world!~n"), 
      loop() 
end. 

je reçois:

Eshell V5.7.5 (abort with ^G) 
1> Pid = spawn(fun test:loop/0). 
<0.35.0> 
2> L = [Pid]. 
[<0.35.0>] 
3> length(L). 
1 
3

Le problème est que si <0.46.0> est la façon dont un PID obtient imprimé, il ne peut pas être entré cette façon. Vous pouvez utiliser list_to_pid("<0.46.0>") à la place. Bien sûr, une fois que vous avez un PID (créé de cette manière, renvoyé par spawn, etc.), il peut être stocké dans une liste et récupéré comme n'importe quel autre terme Erlang.

10

Vous pouvez également construire un Pid à partir de ses trois composants en utilisant pid/3.

1> longueur ([pid (0,35,0)]). Sachez que l'utilisation de l'une de ces techniques pour construire Pid ne fonctionne pas si vous construisez un pid sur un autre nœud que celui sur lequel il a été créé.

Le problème de votre programme est différent.

{badarg, [{erlang, longueur, [0.46.0 <>]}, {barber1, waitingRoom, 2}]}

Un appel à erlang: longueur/1 a créé un badarg. Le troisième élément de {erlang, length, [< 0.46.0>]} est la liste des arguments passés à erlang: length. Donc c'est équivalent à:

1> erlang: longueur (pid (0,46,0)).

où vous aviez l'intention:

1> Erlang: longueur ([pid (0,46,0)]).

(Fâcheusement, le shell Erlang cache maintenant la représentation interne Erlang d'erreurs de vous Remplacer l'erreur ci-dessus.

** Erreur d'exception: mauvaise argument en longueur de fonction/1 appelé longueur (< 0.35.0 >)

qui est beaucoup plus facile à comprendre, mais moins utile, car il est dans la manière d'apprendre la compétence essentielle de l'interprétation vous des erreurs Erlang.)

2

la méthode standard pour obtenir un pid est de prendre la valeur de retour d'une fonction de réapparition, soit spawn/1, spawn/3, spawn_link/1, spawn_link/3, et les équivalents proc_lib.

Un moyen simple d'écrire un pid est avec la fonction c: pid/3, appelé c:pid(0,25,0), qui renverra <0.25.0>. C'est une fonction de raccourci pour le shell. Sinon, vous pouvez utiliser list_to_pid/1 comme mentionné par Alexey Romanov. Cependant, vous devez être conscient du rôle des pids avant d'essayer de les construire à la main. Le pid agit comme l'identifiant personnel d'un processus et ne doit être utilisé que par ceux qui le connaissent. Si vous n'avez pas déjà le pid dans votre main, alors vous ne devriez probablement pas être déjà en sa possession. Indirectement, ceci est destiné à conduire à l'isolation des différentes parties d'un programme seulement se soucier de ces bits que vous avez engendrés et avoir chaque partie de votre programme esprit sa propre entreprise.

Le moyen le plus propre de le faire est donc d'utiliser la valeur de retour d'une fonction spawn. La génération d'un pid à la main ne devrait être qu'une solution de débogage.

5

Ce message d'erreur:

=ERROR REPORT==== 1-Jul-2010::05:50:40 === 
Error in process <0.44.0> with exit value: 
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]} 

signifie que vous appeliez length(<0.46.0>), paslength([<0.46.0>]) (ignorant pour le moment que PIDs ne peut être écrit, pas lu). Dans la trace de la pile, la fonction la plus haute aura la liste des arguments. Puisque length prend un argument, cette liste a un seul argument: vous prenez la longueur d'un PID, ce qui échoue évidemment, puisque seules les listes ont des longueurs.