zoukankan      html  css  js  c++  java
  • go中的并发(goroutine) Yang

    package main
    
    import (
    	"fmt"
    	"runtime"
    )
    
    func main() {
    	//goroutine 其实就是线程,但它比线程小,执行goroutine时只需较少的栈内存(4~5KB)
    	//c#中新建一个thread要分配1M的内存栈。所以,goroutine可以同时运行比较多的并发任务
    	//goroutine也正是因为这个原因比thread更易用、更高效、更轻便
    	//goroutine 通过关键字go实现,go  funcName(参数)
    	//示例
    	//go sayHello("anther--Hello")
    	//sayHello("main--World")
    
    	//channels,channel类型,可以接收和发送数据
    	//必须使用make来创建channel并指定要发送到channel的值的类型
    	//ci := make(chan int)         //可以发送int到ci这个channel(从这个channel取出的也是int类型)
    	//cs := make(chan string)      //可以发送string到string这个channel(从这个channel取出的也是string类型)
    	//cf := make(chan interface{}) //可以发送interface{}到cf这个channel(从这个channel取出的也是interface{}类型)
    	//ch <- v                      //将v发送到channel ch
    	//v := <-ch                    //从channel中取值并赋值给v
    
    	//示例
    	/*
    		arr := []int{7, 2, 8, -9, 4, 0}
    		c := make(chan int)
    		go sum(arr[:len(arr)/2], c)
    		go sum(arr[len(arr)/2:], c)
    		x, y := <-c, <-c
    		fmt.Println(x, y, x+y)
    	*/
    	//Buffered Channels
    
    	//下面这个channel只有存4个int类型的数据,写入前4个时,不会阻塞 ,
    	//当写入第5个时,需要从chanel中读出1个,空出空间才能继续写入
    	//ch := make(chan int, 4)
    
    	//range、close 遍历和读取channel
    	//for i := range c能够不断的读取channel里面的数据,直到该channel被显式的关闭
    	//应该在生产者的地方关闭channel,而不是消费的地方去关闭它,这样容易引起panic
    	//消费方可以通过语法v, ok := <-ch测试channel是否被关闭。
    	//如果ok返回false,那么说明channel已经没有任何数据并且已经被关闭。
    	/*
    		ch := make(chan int, 10)
    		go fibonacci(cap(ch), ch)
    		for value := range ch {
    			fmt.Printf("%d\t", value)
    		}
    	*/
    
    	//select  类似于switch,选择一个符合条件的channel执行
    	//select 也有一个default:它是当channel阻塞(即没有空间)时执行
    	c := make(chan int)
    	quit := make(chan int)
    	go func() {
    		for i := 0; i < 10; i++ {
    			fmt.Println(<-c)
    		}
    		quit <- 0
    	}()
    	fibonacciSelect(c, quit)
    
    	//runtime中的goroutine函数
    	//退出当前执行的goroutine,但是defer函数还会继续调用
    	Goexit()
    	//sleep让出当前goroutine的执行权限,调度器安排其他等待的任务运行,并在下次某个时候从该位置恢复执行。
    	Gosched()
    	//返回 CPU 核数量
    	NumCPU()
    	//返回正在执⾏行和排队的任务总数
    	NumGoroutine()
    	//用来设置可以运行的CPU核数
    	GOMAXPROCS()
    
    }
    
    func sayHello(str string) {
    	for i := 0; i < 5; i++ {
    		//相当于c#中的sleep()
    		runtime.Gosched()
    		fmt.Println(str)
    	}
    }
    
    func sum(a []int, c chan int) {
    	sum := 0
    	for _, value := range a {
    		sum += value
    	}
    	c <- sum
    
    }
    
    func fibonacci(n int, c chan int) {
    	x, y := 1, 1
    	for i := 0; i < n; i++ {
    		c <- x
    		x, y = y, x+y
    	}
    	close(c)
    }
    
    func fibonacciSelect(c, quit chan int) {
    	x, y := 1, 1
    	for {
    		select {
    		case c <- x:
    			x, y = y, x+y
    		case <-quit:
    			fmt.Println("quit")
    			return
    			//default:
    			// 当c阻塞的时候执行这里
    		}
    	}
    }
    
  • 相关阅读:
    [原创]K8 Struts2 Exp 20170310 S2-045(Struts2综合漏洞利用工具)
    [原创]Struts2奇葩环境任意文件上传工具
    Nmap扫描基础常用命令(包含进阶使用)
    Burp Suite Intruder中爆破模式介绍
    Debian Security Advisory(Debian安全报告) DSA-4412-1 drupal7 security update
    Debian Security Advisory(Debian安全报告) DSA-4411-1 firefox-esr security update
    Debian Security Advisory(Debian安全报告) DSA-4410-1 openjdk-8 security update
    kindeditor<=4.1.5 文件上传漏洞利用
    Access数据库SQL注入(Access SQL Injection)
    渗透测试常见开放端口及利用
  • 原文地址:https://www.cnblogs.com/Yang2012/p/3000293.html
Copyright © 2011-2022 走看看