Python中的并发控制

最近有个需求,要大批量写数据,项目是用Python写的。所以有个问题就是如何使用Python做并发控制,如果是Go语言,那么就可以使用 WaitGroup

package main

import (
	"sync"
)

type httpPkg struct{}

func (httpPkg) Get(url string) {}

var http httpPkg

func main() {
	var wg sync.WaitGroup
	var urls = []string{
		"http://www.golang.org/",
		"http://www.google.com/",
		"http://www.somestupidname.com/",
	}
	for _, url := range urls {
		// Increment the WaitGroup counter.
		wg.Add(1)
		// Launch a goroutine to fetch the URL.
		go func(url string) {
			// Decrement the counter when the goroutine completes.
			defer wg.Done()
			// Fetch the URL.
			http.Get(url)
		}(url)
	}
	// Wait for all HTTP fetches to complete.
	wg.Wait()
}

但是这样还只能做到等待所有任务完成后再退出,但是并发控制就得用别的方法,比如使用一个channel或者是加锁。但是Python总是有 非常成熟的方案:concurrent.futures.Executor。

Executor有两个具体实现:ThreadPoolExecutor 和 ProcessPoolExecutor,分别是线程池和进程池。用法都是一样的,都符合 Executor 的接口定义。我们来看实际例子:

from concurrent.futures import ThreadPoolExecutor
import time


def loooooong_task(i):
    print("task %s sleeping..." % i)
    time.sleep(10)
    print("task %s done..." % i)


with ThreadPoolExecutor(max_workers=2) as executor:
    for i in range(10):
        executor.submit(loooooong_task, i)

是不是非常简单,这就是Python的魔力所在。


附:另外还可以参考参考 gevent的pool


参考资料:


更多文章
  • unittest 源代码阅读
  • APUEv3 - 重读笔记
  • Mock源码阅读与分析
  • Thinking in Python
  • 我的代码进CPython标准库啦
  • Python零碎小知识
  • Python和单元测试
  • 工作一年的总结
  • MongoDB 的一些坑
  • Python 的继承
  • Python的yield关键字有什么作用?
  • 借助coroutine用同步的语法写异步
  • Python3函数参数中的星号
  • 使用Git Hooks
  • Token Bucket 算法