golang基础学习(go程、信道)

本文探讨了Go语言中的并发机制,重点介绍了轻量级线程(goroutine)和信道(channel)的使用。通过示例展示了如何通过信道实现goroutine间的通信,以及信道的阻塞和缓冲区特性。同时,对比了C#中实现类似功能的方式,突出了Go语言在并发处理上的优势。
摘要由CSDN通过智能技术生成

go程、信道
  • go程 轻量级线程
  • 分配到同一地址空间、而不像线程那样分配独立的栈空间,文档里比较有意思的一句话:不要通过共享内存来沟通、而是通过沟通来共享内存
  • 下面程序流程
    main中启动2个拼接字符串的go程,明显可以看出hello拼接耗时更短、world拼接耗时很长
    随后使用res_1接收信道c中的数据流(此时阻塞),当hello先行拼接成功,数据流成功从c流向res_1后,执行fmt打印res_1
func say(s string, delay int, c chan string) {
	var res string
	for i := 0; i < 5; i++ {
		time.Sleep(time.Duration(delay) * time.Millisecond)
		res += s
	}
	c <- res
}

func main() {
	c := make(chan string)
	go say("world", 1000, c)
	go say("hello", 500, c)
	res_1 := <-c
	fmt.Println("1:	", res_1)
	res_2 := <-c
	fmt.Println("2:	", res_2)

}
结果:
	1:	 hellohellohellohellohello
	2:	 worldworldworldworldworld

  • 信道不管是接收还是发送均会出现阻塞、信道接收将会检测信道缓冲区大小,足够将流入、不够将阻塞,make第二个参数设定缓冲区大小。
func main() {
	c := make(chan int, 2)
	c <- 1
	c <- 2
	fmt.Println("流入3前")
	c <- 3
	fmt.Println("流入3后")
}
  • 信道可以通过close(ch)关闭、也可以通过for i := range ch 来循环获取信道的值,直到ch被关闭

C#实现类似go程和Channel

原文实现

    public class Channel<T>
    {
        T _value;
        // 最大一个信号 初始为0 无法使用信号量
        Semaphore _canReceive = new Semaphore(0, 1);
        // 最大一个信号 初始可使用信号量为 1
        Semaphore _canSend = new Semaphore(1, 1);

        public T Receive()
        {
            // 无法接收
            _canReceive.WaitOne();
            T value = _value;
            // 可以发送
            _canSend.Release();
            return value;
        }

        public void Send(T value)
        {
            // 无法发送
            _canSend.WaitOne();
            _value = value;
            // 可以接收
            _canReceive.Release();
        }
    }

    public static class SimulationGolang
    {
        public static void go(Action action)
        {
            new Thread(new ThreadStart(action)).Start();
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            string res = string.Empty;

            var ch = new Channel<string>();

            Console.WriteLine($"ID:{Thread.CurrentThread.ManagedThreadId}, 启动");

            SimulationGolang.go(() =>
            {
                for (int i = 0; i < 3; i++)
                {
                    Thread.Sleep(1000 * i);
                    ch.Send("Hello");
                    Console.WriteLine($"ID:{Thread.CurrentThread.ManagedThreadId}发送:Hello");
                }
            });

            for (int i = 0; i < 3; i++)
            {
                res += ch.Receive();
                res += "\n";
                Console.WriteLine($"主线程接收...");
            }

            Console.WriteLine("最终接收:" + res);
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值