You are previewing Erlang Programming.

Erlang Programming

Cover of Erlang Programming by Simon Thompson... Published by O'Reilly Media, Inc.
  1. Erlang Programming
    1. SPECIAL OFFER: Upgrade this ebook with O’Reilly
    2. Foreword
    3. Preface
      1. Francesco: Why Erlang?
      2. Simon: Why Erlang?
      3. Who Should Read This Book?
      4. How to Read This Book
      5. Conventions Used in This Book
      6. Using Code Examples
      7. Safari® Books Online
      8. How to Contact Us
      9. Acknowledgments
    4. 1. Introduction
      1. Why Should I Use Erlang?
      2. The History of Erlang
      3. Erlang’s Characteristics
      4. Erlang and Multicore
      5. Case Studies
      6. How Should I Use Erlang?
    5. 2. Basic Erlang
      1. Integers
      2. The Erlang Shell
      3. Floats
      4. Atoms
      5. Booleans
      6. Tuples
      7. Lists
      8. Term Comparison
      9. Variables
      10. Complex Data Structures
      11. Pattern Matching
      12. Functions
      13. Modules
      14. Exercises
    6. 3. Sequential Erlang
      1. Conditional Evaluations
      2. Guards
      3. Built-in Functions
      4. Recursion
      5. Runtime Errors
      6. Handling Errors
      7. Library Modules
      8. The Debugger
      9. Exercises
    7. 4. Concurrent Programming
      1. Creating Processes
      2. Message Passing
      3. Receiving Messages
      4. Registered Processes
      5. Timeouts
      6. Benchmarking
      7. Process Skeletons
      8. Tail Recursion and Memory Leaks
      9. A Case Study on Concurrency-Oriented Programming
      10. Race Conditions, Deadlocks, and Process Starvation
      11. The Process Manager
      12. Exercises
    8. 5. Process Design Patterns
      1. Client/Server Models
      2. A Process Pattern Example
      3. Finite State Machines
      4. Event Managers and Handlers
      5. Exercises
    9. 6. Process Error Handling
      1. Process Links and Exit Signals
      2. Robust Systems
      3. Exercises
    10. 7. Records and Macros
      1. Records
      2. Macros
      3. Exercises
    11. 8. Software Upgrade
      1. Upgrading Modules
      2. Behind the Scenes
      3. Upgrading Processes
      4. The .erlang File
      5. Exercise
    12. 9. More Data Types and High-Level Constructs
      1. Functional Programming for Real
      2. Funs and Higher-Order Functions
      3. List Comprehensions
      4. Binaries and Serialization
      5. References
      6. Exercises
    13. 10. ETS and Dets Tables
      1. ETS Tables
      2. Dets Tables
      3. A Mobile Subscriber Database Example
      4. Exercises
    14. 11. Distributed Programming in Erlang
      1. Distributed Systems in Erlang
      2. Distributed Computing in Erlang: The Basics
      3. The epmd Process
      4. Exercises
    15. 12. OTP Behaviors
      1. Introduction to OTP Behaviors
      2. Generic Servers
      3. Supervisors
      4. Applications
      5. Release Handling
      6. Other Behaviors and Further Reading
      7. Exercises
    16. 13. Introducing Mnesia
      1. When to Use Mnesia
      2. Configuring Mnesia
      3. Transactions
      4. Partitioned Networks
      5. Further Reading
      6. Exercises
    17. 14. GUI Programming with wxErlang
      1. wxWidgets
      2. wxErlang: An Erlang Binding for wxWidgets
      3. A First Example: MicroBlog
      4. The MiniBlog Example
      5. Obtaining and Running wxErlang
      6. Exercises
    18. 15. Socket Programming
      1. User Datagram Protocol
      2. Transmission Control Protocol
      3. The inet Module
      4. Further Reading
      5. Exercises
    19. 16. Interfacing Erlang with Other Programming Languages
      1. An Overview of Interworking
      2. Interworking with Java
      3. C Nodes
      4. Erlang from the Unix Shell: erl_call
      5. Port Programs
      6. Library Support for Communication
      7. Linked-in Drivers and the FFI
      8. Exercises
    20. 17. Trace BIFs, the dbg Tracer, and Match Specifications
      1. Introduction
      2. The Trace BIFs
      3. Tracing Calls with the trace_pattern BIF
      4. The dbg Tracer
      5. Match Specifications: The fun Syntax
      6. Match Specifications: The Nuts and Bolts
      7. Further Reading
      8. Exercises
    21. 18. Types and Documentation
      1. Types in Erlang
      2. TypEr: Success Types and Type Inference
      3. Documentation with EDoc
      4. Exercises
    22. 19. EUnit and Test-Driven Development
      1. Test-Driven Development
      2. EUnit
      3. The EUnit Infrastructure
      4. Testing State-Based Systems
      5. Testing Concurrent Programs in Erlang
      6. Exercises
    23. 20. Style and Efficiency
      1. Applications and Modules
      2. Processes and Concurrency
      3. Stylistic Conventions
      4. Coding Strategies
      5. Efficiency
      6. And Finally...
    24. A. Using Erlang
      1. Getting Started with Erlang
      2. Tools for Erlang
      3. Where to Learn More
    25. Index
    26. About the Authors
    27. Colophon
    28. SPECIAL OFFER: Upgrade this ebook with O’Reilly

Registered Processes

It is not always practical to use pids to communicate with processes. To use a pid, a process needs to be notified of it and store its value. It is common to register processes that offer specific services with an alias, a name that can be used instead of the pid. You register a process with the register(Alias, Pid) BIF, where Alias is an atom and Pid is the process identifier. You do not have to be a parent or a child of the process to call the register BIF; you just need to know its process identifier.

Once a process has been registered, any process can send a message to it without having to be aware of its identifier (see Figure 4-9). All the process needs to do is use the Alias ! Message construct. In programs, the alias is usually hardcoded in. Other BIFs which are directly related to process registration include unregister(Pid); registered(), which returns a list of registered names; and whereis(Alias), which returns the pid associated with the Alias.

Sending a message to a registered process

Figure 4-9. Sending a message to a registered process

Look at Example 4-2, which is a variant of Example 4-1. We have removed the Pid!stop expression at the end of the go/0 function, and instead of binding the return value of spawn/3, we pass it as the second argument to the register BIF. The first argument to register is echo, the atom we use to name the process. This alias is used to send the message to the newly spawned child.

Example 4-2. The registered echo process

-export([go/0, loop/0]).

go() ->
  register(echo, spawn(echo, loop, [])),
  echo ! {self(), hello},
    {_Pid, Msg} ->

loop() ->
    {From, Msg} ->
      From ! {self(), Msg},
    stop ->

It is not mandatory, but it is considered a good practice to give your process the same name as the module in which it is defined.

Update your echo module with the changes we just discussed and try out the new BIFs you have just read about in the shell. Test the new implementation of echo, inspecting its state with the i() and regs() shell commands. Note how the shell process sends the stop message to the echo process without knowing its pid, and how whereis/1 returns undefined if the process does not exist:

1> c(echo).
2> echo:go().
3> whereis(echo).
4> echo ! stop.
5> whereis(echo).
6> regs().

** Registered procs on node nonode@nohost **
Name                   Pid            Initial Call           Reds Msgs
application_controlle  <0.5.0>        erlang:apply/2         4426    0
code_server            <0.20.0>       erlang:apply/2       112203    0
ddll_server            <0.10.0>       erl_ddll:init/1          32    0
erl_prim_loader        <0.2.0>        erlang:apply/2       206631    0
error_logger           <0.4.0>        gen_event:init_it/6     209    0
file_server            <0.19.0>       erlang:apply/2           12    0
file_server_2          <0.18.0>       file_server:init/1    25411    0
global_group           <0.17.0>       global_group:init/1      71    0
global_name_server     <0.12.0>       global:init/1            60    0
inet_db                <0.15.0>       inet_db:init/1          103    0
init                   <0.0.0>        otp_ring0:start/2      5017    0
kernel_safe_sup        <0.26.0>       supervisor:kernel/1      61    0
kernel_sup             <0.9.0>        supervisor:kernel/1    1377    0
rex                    <0.11.0>       rpc:init/1               44    0
user                   <0.23.0>       user:server/2          1459    0

** Registered ports on node nonode@nohost **
Name                  Id              Command

The shell command regs() prints out all the registered processes. It might be an alternative to i() when retrieving system information in a system with large quantities of processes. In the preceding example, the echo process is not among the processes listed, as we have stopped it. Instead, you are seeing all of the registered system processes.


It is a feature of Erlang memory management that atoms are not garbage collected. Once you’ve created an atom, it remains in the atom table regardless of whether it is referenced in the code. This can be a potential problem if you decide to register transient processes with an alias derived from converting a string to an atom with the list_to_atom/1 BIF. If you have millions of users logging on to your system every day and you create a registered process for the duration of their sessions, don’t be surprised if you end up running out of memory.

You would be much better off storing the mapping of users to pids in a session table. It is best to register only processes with a long life span, and if you really must convert a string to use as an alias, use list_to_existing_atom/1 to ensure that your system does not suffer memory leakages.

Sending messages to nonexistent registered processes causes the calling process to terminate with a badarg (see Figure 4-10). This behavior is different from sending a message to a process identifier for a nonexistent process, as registered processes are assumed to provide a service. The absence of a registered process is therefore treated as a bug. If your program might be sending messages to nonexistent registered processes and you do not want the calling process to terminate, wrap a try ... catch around the call.

Sending messages to non-registered processes

Figure 4-10. Sending messages to non-registered processes

The best content for your career. Discover unlimited learning on demand for around $1/day.