Structured concurrency

简介 定义 根据维基百科的解释: Structured concurrency is a programming paradigm aimed at improving the clarity, quality, and development time of a computer program by using a structured approach to concurrent programming. The core concept is the encapsulation of concurrent threads of execution (here encompassing kernel and userland threads and processes) by way of control flow constructs that have clear entry and exit points and that ensure all spawned threads have completed before exit. Such encapsulation allows errors in concurrent threads to be propagated to the control structure’s parent scope and managed by the native error handling mechanisms of each particular computer language. It allows control flow to remain readily evident by the structure of the source code despite the presence of concurrency. To be effective, this model must be applied consistently throughout all levels of the program – otherwise concurrent threads may leak out, become orphaned, or fail to have runtime errors correctly propagated. ...

2022年8月1日 · zhoukuncheng

Go 1.18 泛型介绍

什么是泛型 泛型程序设计(generic programming)是程序设计语言的一种风格或范式。泛型允许程序员在编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。 Golang 泛型基本用法 示例 map 操作 package main import ( "fmt" ) func mapFunc[T any, M any](a []T, f func(T) M) []M { n := make([]M, len(a), cap(a)) for i, e := range a { n[i] = f(e) } return n } func main() { vi := []int{1, 2, 3, 4, 5, 6} vs := mapFunc(vi, func(v int) string { return "<" + fmt.Sprint(v * v) + ">" }) fmt.Println(vs) } min max 函数 ...

2022年3月16日 · zhoukuncheng

通过 gRPC-Gateway 开发 RESTful API

gRPC-Gateway 简介 gRPC-Gateway 是 protoc 的一个插件,工作机制是读取一个 gRPC 服务定义并生成一个反向代理服务器,将 RESTful JSON API 翻译成 gRPC。 这个服务器是根据编写的 gRPC 定义中的自定义选项来生成的。 安装使用 依赖工具 工具 简介 安装 protobuf protocol buffer 编译所需的命令行 http://google.github.io/proto-lens/installing-protoc.html protoc-gen-go 从 proto 文件,生成 .go 文件 https://grpc.io/docs/languages/go/quickstart/ protoc-gen-go-grpc 从 proto 文件,生成 gRPC 相关的 .go 文件 https://grpc.io/docs/languages/go/quickstart/ protoc-gen-grpc-gateway 从 proto 文件,生成 gRPC-gateway 相关的 .go 文件 https://github.com/grpc-ecosystem/grpc-gateway#installation protoc-gen-openapiv2 从 proto 文件,生成 swagger 文档所需的参数文件 https://github.com/grpc-ecosystem/grpc-gateway#installation buf protobuf 管理工具,可选,简化命令行操作和protobuf 文件管理 https://docs.buf.build/installation 步骤 编写buf配置 buf.gen.yaml version: v1beta1 plugins: - name: go out: internal/proto opt: - paths=source_relative - name: go-grpc out: internal/proto opt: - paths=source_relative - require_unimplemented_servers=false - name: grpc-gateway out: internal/proto opt: - paths=source_relative - name: openapiv2 out: openapi opt: - json_names_for_fields=false buf.yaml ...

2022年3月13日 · zhoukuncheng

Python 与 Go 之间的并发模式差异

Python并发方式 在 Python 中,早期并发方式以传统的多进程和多线程为主,类似 Java,同时,有不少第三方的异步方案(gevent/tornado/twisted 等)。 在 Python 3 时期,官方推出了 asyncio 和 async await 语法,作为 Python 官方的协程实现,而逐渐普及。 进程 多进程编程示例: from multiprocessing import Process def f(name): print('hello', name) if __name__ == '__main__': p = Process(target=f, args=('bob',)) p.start() p.join() multiprocessing 与 threading 的 API 接近,比较容易创建多进程的程序,是 Python 官方推荐作为绕过多线程 GIL 限制的一种方案。 但需要注意,创建进程的参数需要能被 pickle 序列化,最好使用 Pipe、Queue 等进程安全的数据结构(官方文档的 Programming guidelines) 线程 多线程代码示例: from threading import Thread def f(name): print('hello', name) if __name__ == '__main__': p = Thread(target=f, args=('bob',)) p.start() p.join() # 线程池方式 with ThreadPoolExecutor(max_workers=1) as executor: future = executor.submit(pow, 323, 1235) print(future.result()) Cpython 线程的缺陷:GIL(全局解释器锁) GIL 是 Cpython 执行 Python 字节码时的一把全局锁,导致解释器在 CPU 密集型任务时不能充分利用多核,而 IO 密集型任务会释放 GIL。 如果想绕过 GIL,只能换成多进程方式,或者通过C 扩展绕过。 ...

2021年8月30日 · zhoukuncheng

编译 CPython 心得

什么情况下需要自己编译 CPython 大多数操作系统都提供了编译好的 CPython 版本,一般直接通过包管理器安装就能满足需求,但是某些情况下,就需要自己编译 CPython 来满足特定需求了: 操作系统提供的 Python 版本太低,并且 Python 官网、系统包管理源没有提供预编译的新版本 Python 预编译版本不符合性能、扩展等方面的要求,比如没有开启编译器优化、OpenSSL/SQLite 版本不满足要求等 参与 CPython 开发或者尝鲜,尝试 Alpha/Beta/RC 等版本的 Python ​ ​ 低版本 Linux 发行版上编译 CPython 时的注意事项 OpenSSL 因为 CentOS 6 官方源中的 OpenSSL 版本过低,不满足 Python 3.7 及之后的要求,所以直接 configure & make 会报错,解决办法: 参考 Python 3.7 on CentOS 6 , 提前编译 OpenSSL, 编译 CPython 时修改 Modules/Setup 文件,并且指定环境变量 LDFLAGS="-Wl,-rpath=/usr/local/openssl11/lib" , 指定参数 -with-openssl=/usr/local/openssl11 。 SQLite Jupyter 等软件依赖 SQLite, 所以编译 CPython 时不仅要注意 SQLite 版本,也要开启 --enable-loadable-sqlite-extensions , 参考:How to use enable_load_extension from sqlite3? ...

2020年7月24日 · zhoukuncheng