[TIPS] 有关 Read-Write Lock

关于读写锁死锁的问题 最近在写框架绑定服务提供者的时候,遇到了编译出错,出现了死锁。主要代码如下: func (hade *HadeContainer) Bind(provider ServiceProvider) error { hade.lock.Lock() defer hade.lock.Unlock() key := provider.Name() hade.providers[key] = provider // if provider is not defer if provider.IsDefer() == false { if err := provider.Boot(hade); err != nil { return err } // 实例化方法 // 省略... } return nil } 这段代码调用了 provider.Boot() 方法 func (provider *HadeEnvProvider) Boot(c framework.Container) error { app := c.MustMake(contract.AppKey).(contract.App) // 省略... } func (hade *HadeContainer) MustMake(key string) interface{} { serv, err := hade.

[TIPS] Undefined: syscall.Kill on Windows

Undefined: syscall.Kill on Windows 最近在 Windows10 下开发 Go 的守护进程,在做命令重启的时候用到了 syscall.Kill 这个函数,编译报错。IDE 显示 Kill 函数红色,查阅了 Go doc 确实存在有 Kill 函数,清除缓存和重启IDE 都无果。 原来是 syscall 包跟操作系统有关,syscall.Kill 只支持 Unix/Linux/Mac 系统,不支持 Windows 系统。 之前的代码如下: if err := syscall.Kill(pid, syscall.SIGTERM); err != nil { return err } // Mac/Linux 的写法 修改成如下 调用 os 包 pro, err := os.FindProcess(pid) if err != nil { return err } err = pro.Kill() if err != nil { return err } // Windows的写法

关于并发和 I/O 模型

并发和并行 一提到并发,通常就会提起并行,那么什么是并发,什么又是并行? 并行意味着一个任务同时有多个可执行单元在运行。 从操作系统的角度来看,并行意味着一个任务被多个CPU 核心执行。 单独一个 CPU 核心不能执行并行计算,它可以是在多个任务中来回切换地进行运算,但是不能被称为并行。并行的必要条件是多CPU 核心 或多 CPU 的计算环境。 并发意味着在同一时期内执行多个任务,可以在一个 CPU 核心上,也可以在多个 CPU 核心上。但是在同一时期,这些任务不一定都处于运行状态,这取决于 CPU 核心或者 CPU的数量。 阻塞 IO 、 非阻塞 IO和多路复用 IO 阻塞 IO 最传统的一种 IO 模型,即在读写数据的过程中会发生阻塞现象。 非阻塞 IO 用户发起 IO 请求后, 并不需要等待,而是马上就得到一个结果。用户线程需要不断地询问内核数据是否就绪,会一直占用 CPU 多路复用 IO 会有一个线程不断去轮询多个 socket 的状态,只有当 socket 真正有读写事件时,才真正调用实际的 IO读写操作,因为只需要用一个线程就可以管理多个 socket, 系统不需要建立新的进程或者线程,也不必维护这些线程和进程,所以大大减少了资源占用。多路复用有多种方案,比如 select poll epoll 之后另开一篇再表。 另外IO 模型还有 信号驱动 IO, 异步IO, 也在之后的文章中再讲。 并发 IO 模型 1. 单进程阻塞IO 最原始的一种 IO 模型,任务只能一个接着一个按序执行,哪怕 CPU 空闲着。只有一个 PHP脚本在执行。 2. 多进程阻塞IO 这是目前 PHP-FPM 和大部分 CGI 脚本(Python、Ruby)所用的模型