Go语言小试牛刀---几个简单的例子
整理资料,发现之前手写的Go语言资料,现在贴过来。
第一个:Channel的使用,创建一个随机数
package main import "fmt"
import "runtime" func rand_generator_2() chan int{
out := make(chan int)
go func(){
for{
out<-rand.Int()
}
}()
return out
} func main(){
rand_service_handler := rand_generator_2()
fmt.Printf("%d\n",<-rand_service_handler)
}
第二个:实现通过Channel通道求和的例子
package main
type NodeInterface interface {
  receive(i int)
  run() int
}
type Node struct {
  name string
  in_degree int
  in_ch chan int
  out_ch chan int
  inode NodeInterface
}
func NewNode(name string, inode NodeInterface) *Node {
  //创建一个Node,拥有两个channel
  return &Node{name, 0, make(chan int), make(chan int), inode}
}
func (from *Node) ConnectTo(to *Node) {
  to.in_degree++
  go func() {
    i := <- from.out_ch
    to.in_ch <- i
  }()
}
func (n *Node) Run() {
  go func() {
    defer func() {
      if x := recover(); x != nil {
        println(n.name, "panic with value ", x)
        panic(x)
      }
      println(n.name, "finished");
    }()
    for n.in_degree > 0 {
      received := <- n.in_ch
      n.inode.receive(received)
      n.in_degree--
    }
    ret := n.inode.run()
    n.out_ch <- ret
  }()
}
type DoubleNode struct {
  data int
}
//创建一个新的Node
func NewDoubleNode(name string, data int) *Node {
  return NewNode(name, &DoubleNode{data})
}
func (n *DoubleNode) receive(i int) {
}
func (n *DoubleNode) run() int {
  return n.data * 2
}
type SumNode struct {
  data int
}
func NewSumNode(name string) *Node {
  return NewNode(name, &SumNode{0})
}
func (n *SumNode) receive(i int) {
  n.data += i
}
func (n *SumNode) run() int {
  return n.data
}
func main() {
  sum := NewSumNode("sum")
  sum.Run()
  for _, num := range [5]int{1, 2, 3, 5, 6} {
    node := NewDoubleNode("double", num)
    node.ConnectTo(sum)
    node.Run()
  }
  println(<- sum.out_ch)
}
第三个例子:Go语言的并发操作,go语言可以适配机器的cpu达到最大并发
package main import (
"fmt"
"runtime"
) var workers = runtime.NumCPU() type Result struct {
jobname string
resultcode int
resultinfo string
} type Job struct {
jobname string
results chan<- Result
} func main() { // go语言里大多数并发程序的开始处都有这一行代码, 但这行代码最终将会是多余的,
// 因为go语言的运行时系统会变得足够聪明以自动适配它所运行的机器
runtime.GOMAXPROCS(runtime.NumCPU()) // 返回当前处理器的数量
fmt.Println(runtime.GOMAXPROCS(0))
// 返回当前机器的逻辑处理器或者核心的数量
fmt.Println(runtime.NumCPU()) // 模拟8个工作任务
jobnames := []string{"gerry", "wcdj", "golang", "C++", "Lua", "perl", "python", "C"}
doRequest(jobnames)
} func doRequest(jobnames []string) { // 定义需要的channels切片
jobs := make(chan Job, workers)
results := make(chan Result, len(jobnames))
done := make(chan struct{}, workers) // ---------------------------------------------
/*
* 下面是go协程并发处理的一个经典框架
*/ // 将需要并发处理的任务添加到jobs的channel中
go addJobs(jobs, jobnames, results) // Executes in its own goroutine // 根据cpu的数量启动对应个数的goroutines从jobs争夺任务进行处理
for i := 0; i < workers; i++ {
go doJobs(done, jobs) // Each executes in its own goroutine
} // 新创建一个接受结果的routine, 等待所有worker routiines的完成结果, 并将结果通知主routine
go awaitCompletion(done, results) // 在主routine输出结果
processResults(results)
// --------------------------------------------- } func addJobs(jobs chan<- Job, jobnames []string, results chan<- Result) {
for _, jobname := range jobnames { // 在channel中添加任务
jobs <- Job{jobname, results}
}
close(jobs)
} func doJobs(done chan<- struct{}, jobs <-chan Job) { // 在channel中取出任务并计算
for job := range jobs { /*
* 定义类型自己的方法来处理业务逻辑, 实现框架和业务分离
*/
job.Do()
} // 所有任务完成后的结束标志, 一个空结构体切片
done <- struct{}{}
} // 方法是作用在自定义类型的值上的一类特殊函数
func (job Job) Do() { // 打印当前处理的任务名称
fmt.Printf("... doing work in [%s]\n", job.jobname) // 模拟处理结果
if job.jobname == "golang" {
job.results <- Result{job.jobname, 0, "OK"}
} else {
job.results <- Result{job.jobname, -1, "Error"}
}
} func awaitCompletion(done <-chan struct{}, results chan Result) {
for i := 0; i < workers; i++ {
<-done
}
close(results)
} func processResults(results <-chan Result) {
for result := range results {
fmt.Printf("done: %s,%d,%s\n", result.jobname, result.resultcode, result.resultinfo)
}
}
第四个:网络编程方面,基于Go实现Ping的操作,比较难,还未看明白
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // taken from http://golang.org/src/pkg/net/ipraw_test.go package ping import (
"bytes"
"errors"
"net"
"os"
"time"
) const (
icmpv4EchoRequest = 8
icmpv4EchoReply = 0
icmpv6EchoRequest = 128
icmpv6EchoReply = 129
) type icmpMessage struct {
Type int // type
Code int // code
Checksum int // checksum
Body icmpMessageBody // body
} type icmpMessageBody interface {
Len() int
Marshal() ([]byte, error)
} // Marshal returns the binary enconding of the ICMP echo request or
// reply message m.
func (m *icmpMessage) Marshal() ([]byte, error) {
b := []byte{byte(m.Type), byte(m.Code), 0, 0}
if m.Body != nil && m.Body.Len() != 0 {
mb, err := m.Body.Marshal()
if err != nil {
return nil, err
}
b = append(b, mb...)
}
switch m.Type {
case icmpv6EchoRequest, icmpv6EchoReply:
return b, nil
}
csumcv := len(b) - 1 // checksum coverage
s := uint32(0)
for i := 0; i < csumcv; i += 2 {
s += uint32(b[i+1])<<8 | uint32(b[i])
}
if csumcv&1 == 0 {
s += uint32(b[csumcv])
}
s = s>>16 + s&0xffff
s = s + s>>16
// Place checksum back in header; using ^= avoids the
// assumption the checksum bytes are zero.
b[2] ^= byte(^s & 0xff)
b[3] ^= byte(^s >> 8) return b, nil
} // parseICMPMessage parses b as an ICMP message.
func parseICMPMessage(b []byte) (*icmpMessage, error) {
msglen := len(b)
if msglen < 4 {
return nil, errors.New("message too short")
}
m := &icmpMessage{Type: int(b[0]), Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])}
if msglen > 4 {
var err error
switch m.Type {
case icmpv4EchoRequest, icmpv4EchoReply, icmpv6EchoRequest, icmpv6EchoReply:
m.Body, err = parseICMPEcho(b[4:])
if err != nil {
return nil, err
}
}
}
return m, nil
} // imcpEcho represenets an ICMP echo request or reply message body.
type icmpEcho struct {
ID int // identifier
Seq int // sequence number
Data []byte // data
} func (p *icmpEcho) Len() int {
if p == nil {
return 0
}
return 4 + len(p.Data)
} // Marshal returns the binary enconding of the ICMP echo request or
// reply message body p.
func (p *icmpEcho) Marshal() ([]byte, error) {
b := make([]byte, 4+len(p.Data))
b[0], b[1] = byte(p.ID>>8), byte(p.ID&0xff)
b[2], b[3] = byte(p.Seq>>8), byte(p.Seq&0xff)
copy(b[4:], p.Data)
return b, nil
} // parseICMPEcho parses b as an ICMP echo request or reply message body.
func parseICMPEcho(b []byte) (*icmpEcho, error) {
bodylen := len(b)
p := &icmpEcho{ID: int(b[0])<<8 | int(b[1]), Seq: int(b[2])<<8 | int(b[3])}
if bodylen > 4 {
p.Data = make([]byte, bodylen-4)
copy(p.Data, b[4:])
}
return p, nil
} func Ping(address string, timeout int) (alive bool) {
err := Pinger(address, timeout)
alive = err == nil
return
} func Pinger(address string, timeout int) (err error) {
//拨号
c, err := net.Dial("ip4:icmp", address) if err != nil {
return
}
//?
c.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Second))
defer c.Close() //>>
typ := icmpv4EchoRequest
xid, xseq := os.Getpid()&0xffff, 1
wb, err := (&icmpMessage{
Type: typ, Code: 0,
Body: &icmpEcho{
ID: xid, Seq: xseq,
Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3),
},
}).Marshal()
if err != nil {
return
}
if _, err = c.Write(wb); err != nil {
return
}
var m *icmpMessage rb := make([]byte, 20+len(wb)) for {
if _, err = c.Read(rb); err != nil {
return
}
rb = ipv4Payload(rb)
if m, err = parseICMPMessage(rb); err != nil {
return
}
switch m.Type {
case icmpv4EchoRequest, icmpv6EchoRequest:
continue
}
break
}
return
} func ipv4Payload(b []byte) []byte {
if len(b) < 20 {
return b
}
hdrlen := int(b[0]&0x0f) << 2
return b[hdrlen:]
}
Go语言小试牛刀---几个简单的例子的更多相关文章
- 为什么C语言在2013年仍然很重要:一个简单的例子
		附注:在最初的文章里,我没说明进行模2^64的计算——我当然明白那些不是“正确的”斐波那契数列,其实我不是想分析大数,我只是想探寻编译器产生的代码和计算机体系结构而已. 最近,我一直在开发Dynvm— ... 
- Spring-Context之一:一个简单的例子
		很久之前就想系统的学习和掌握Spring框架,但是拖了很久都没有行动.现在趁着在外出差杂事不多,就花时间来由浅入深的研究下Spring框架.Spring框架这几年来已经发展成为一个巨无霸产品.从最初的 ... 
- 扩展Python模块系列(二)----一个简单的例子
		本节使用一个简单的例子引出Python C/C++ API的详细使用方法.针对的是CPython的解释器. 目标:创建一个Python内建模块test,提供一个功能函数distance, 计算空间中两 ... 
- fitnesse - 一个简单的例子(slim)
		fitnesse - 一个简单的例子(slim) 2017-09-30 目录1 编写测试代码(Fixture code)2 编写wiki page并运行 2.1 新建wikiPage 2.2 运行 ... 
- C语言排序算法之简单交换法排序,直接选择排序,冒泡排序
		C语言排序算法之简单交换法排序,直接选择排序,冒泡排序,最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 简单交换法排序 /*简单交换法排序 根据序列中两个记录键值的比较结果来对换这两 ... 
- 从一个简单的例子谈谈package与import机制
		转,原文:http://annie09.iteye.com/blog/469997 http://blog.csdn.net/gdsy/article/details/398072 这两篇我也不知道到 ... 
- [Graphviz]一些简单的例子(未完待续)
		本文参考:http://wenku.baidu.com/link?url=kTPIn5tBY4eboEPZeOZyLwHAq-fSMoTbagsqcG5-IcpL325tnnh3ES8aky-PBjP ... 
- 简单的例子了解自定义ViewGroup(一)
		在Android中,控件可以分为ViewGroup控件与View控件.自定义View控件,我之前的文章已经说过.这次我们主要说一下自定义ViewGroup控件.ViewGroup是作为父控件可以包含多 ... 
- CSharpGL(1)从最简单的例子开始使用CSharpGL
		CSharpGL(1)从最简单的例子开始使用CSharpGL 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo ... 
随机推荐
- strerror线程安全分析
			导读 strerror是否线程安全了? 1 errno是否线程安全? 1 附1:strerror源码 2 附2:__strerror_r源码 2 strerror是否线程安全了? 答案是NO,但它有个 ... 
- heartbeat+nginx搭建高可用HA集群
			前言: HA即(high available)高可用,又被叫做双机热备,用于关键性业务.简单理解就是,有2台机器 A 和 B,正常是 A 提供服务,B 待命闲置,当 A 宕机或服务宕掉,会切换至B机器 ... 
- JAVA IO总结及socket简单实现
			为了方便理解与阐述,先引入两张图: a.Java IO中常用的类 在整个Java.io包中最重要的就是5个类和一个接口.5个类指的是File.OutputStream.InputStream.Writ ... 
- 微信开发之c#下获取jssdk的access_token
			获取access_token是调用微信JS接口的基础,只有得到了它才能得到我们需要的jsapi_ticket并生成签名,然后注入配置信息config. 微信官方文档我就不多做介绍,反正我是踩了不少坑. ... 
- .Net Core配置与自动更新
			.Net Core 将之前Web.Config中的配置迁移到了appsettings.json文件中,并使用ConfigurationBuilder来读取这个配置文件.并可设置在配置文件变化以后,自动 ... 
- C# Log4.Net日志组件的应用系列(二)
			引言 Log4Net应该可以说是.NET中最流行的开源日志组件了.在各种项目框架中可以说是必不可少的组成部分.个人认为Log4Net有下面几个优点: 1. 使用灵活,它可以将日志分不同的等级,以不同的 ... 
- Windows上编译libjpeg
			通常libjpeg可以使用如下命令行生成Visual Studio 2010的项目文件: nmake /f makefile.vc setup-v10 但可惜我们使用的是Visual Studio 2 ... 
- 【QTP专题】05_参数化之Excel
			QTP使用外部Excel实现参数化主要有以下两种方式 导入到DataTable中 Syntax:DataTable.ImportSheet(FileName, SheetSource, SheetDe ... 
- DatagridView 控件列顺序与设置的不一样
			解决方案如下 : 1. dataGridView1.AutoGenerateColumns = false; 2. 绑定的dataSource 中所有的列都要写进去(列一定是绑定的模型中属性) 先在界 ... 
- Windows下使用DOS命令进入MySQL数据库
			先要配置环境变量 MYSQL_HOME : D:\mysql-8.0.11-winx64 Path:%MYSQL_HOME%\bin 1)新建MYSQL_HOME变量,并配置:C:\Program F ... 
