When I first heard about Google’s new language, Go, I got interested and began reading the tutorial here. At first it did not really seem all that interesting. Sure, it was garbage collected and provided some access to lower level stuff, but that is not that different. Then I got near the bottom of the tutorial and it got interesting. The first thing of interest in Go is interfaces. These allow one to easily write generic methods. For example, if i have an interface named Foo that has a method A, and a function that takes Foo as an argument, that function can take any object that implements a function named A with the same prototype. This allows a lot of the functions and objects in the Go standard library to work well together. The other cool part is go routines and channels. A go routine is any function prefixed by the keyword ‘go,’ like:
go myFunction();
This function is then simply by themselves run in the background, no extra work required. Anything that would block the main thread can be dispatched in this way and run independently. One can then use channels to talk between go routines. A channel is kind of like a queue object that data gets pushed into and pulled out of in a FIFO order. One use of channels is to constantly pull new data from a thread running infinitely.
For fun, I created a simple server in Go that uses go routines and channels:
package main
import (
"fmt";
"net";
"log";
)
// This is a comment
// getConnections will run forever, accepting sockets from a listener. This normally would block in a main thread
func getConnections(listener *net.TCPListener, ch chan net.Conn) {
for {
tmp, _ := listener.Accept();
ch <- tmp; // Here we push tmp, a connection of type net.Conn, into a channel
}
}
func main() {
addr, _ := net.ResolveTCPAddr("localhost:6667");
listener , _ := net.ListenTCP("tcp", addr);
conChan := make(chan net.Conn);
log.Stdout("STARTING SERVER...");
go getConnections(listener, conChan); // getConnections will run in the background, forever adding connections to conChan
for {
buf := make([]byte, 256);
con := <-conChan; // Here we pull out the the connection that we pushed in earlier in getConnections
con.Read(buf);
log.Stdoutf("RECIEVED REQUEST FROM %s:\n", con.RemoteAddr().String());
fmt.Printf("%s\n", buf);
con.Close();
}
}
This server will read as much as 256 bytes of data from a connection, print it along with a log, and discard the connection.
Recent Comments