并发编程总结

并发编程:
1. 进程、线程、协程的区别?

2. 线程
  - 基本写法

import threading

# 1. 计算密集型多线程无用 
v1 = [11,22,33] # +1
v2 = [44,55,66] # 100

def func(data,plus):
     for i in range(len(data)):
         data[i] = data[i] + plus

t1 = threading.Thread(target=func,args=(v1,1))
t1.start()

t2 = threading.Thread(target=func,args=(v2,100))
t2.start()


# 2. IO操作 多线程有用 
import threading
import requests
import uuid

url_list = [
'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg',
'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg',
'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg',
]

def task(url):
    ret = requests.get(url)
    file_name = str(uuid.uuid4()) + '.jpg'
    with open(file_name, mode='wb') as f:
         f.write(ret.content)

for url in url_list:

 t = threading.Thread(target=task,args=(url,))
 t.start()
线程

  - 实例化
  - 继承
  - 锁
    - RLock

  - 线程池
3. 进程
  - 基本写法
  - 实例化
  - 继承
  - 锁
  - RLock
  ...
  - 线程池
  - 进程数据共享

4. 协程
  - 协程
  - 协程+IO:gevent

5. IO多路复用
  1. IO多路复用

IO多路复用作用:检测多个socket是否已经发生变化(是否已经连接成功/是否已经获取数据)(可读/可写)

  2. 基于IO多路复用+socket实现并发请求(一个线程100个请求)

IO多路复用 

socket非阻塞 

基于事件循环实现的异步非阻塞框架:lzl

非阻塞:不等待

  异步:执行完某个人物后自动调用我给他的函数。

  

Python中开源 基于事件循环实现的异步非阻塞框架 Twisted 

  

 总结:

1. socket默认是否是阻塞的?阻塞体现在哪里?

2. 如何让socket编程非阻塞?

3. IO多路复用作用?

检测多个socket是否发生变化。

操作系统检测socket是否发生变化,有三种模式:

select:最多1024个socket;循环去检测。

poll:不限制监听socket个数;循环去检测(水平触发)。

epoll:不限制监听socket个数;回调方式(边缘触发)。

Python模块:

select.select 

select.epoll 

4. 提高并发方案:

- 多进程 

- 多线程 

- 异步非阻塞模块(Twisted) scrapy框架(单线程完成并发)

5. 什么是异步非阻塞?

- 非阻塞,不等待。

比如创建socket对某个地址进行connect、获取接收数据recv时默认都会等待(连接成功或接收到数据),才执行后续操作。

如果设置setblocking(False),以上两个过程就不再等待,但是会报BlockingIOError的错误,只要捕获即可。

- 异步,通知,执行完成之后自动执行回调函数或自动执行某些操作(通知)。

比如做爬虫中向某个地址baidu.com发送请求,当请求执行完成之后自执行回调函数。

6. 什么是同步阻塞?

- 阻塞:等 

- 同步:按照顺序逐步执行

key_list = ['alex','db','sb']

for item in key_list:

ret = requests.get('https://www.baidu.com/s?wd=%s' %item)

print(ret.text)

7. 概念 

之前:

# 你写的代码:7000w

v = [

[11,22], # 每个都有一个append方法

[22,33], # 每个都有一个append方法

[33,44], # 每个都有一个append方法

]

# 王思聪

for item in v:

print(item.append)

之后:

class Foo(object):

def __init__(self,data,girl):

self.row = data

self.girl = girl

def append(self,item):

self.row.append(item)

v = [

Foo([11,22],'雪梨'), # 每个都有一个append方法

Foo([22,33],'冰糖'), # 每个都有一个append方法

Foo([33,44],'糖宝'), # 每个都有一个append方法

]

for item in v:

print(item.append)

item.girl

6. 异步/同步 阻塞/非阻塞

import threading

# 1. 计算密集型多线程无用
v1 = [11,22,33] # +1
v2 = [44,55,66] # 100

def func(data,plus):
for i in range(len(data)):
data[i] = data[i] + plus

t1 = threading.Thread(target=func,args=(v1,1))
t1.start()

t2 = threading.Thread(target=func,args=(v2,100))
t2.start()


# 2. IO操作 多线程有用
import threading
import requests
import uuid

url_list = [
'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg',
'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg',
'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg',
]

def task(url):
ret = requests.get(url)
file_name = str(uuid.uuid4()) + '.jpg'
with open(file_name, mode='wb') as f:
f.write(ret.content)

for url in url_list:

t = threading.Thread(target=task,args=(url,))
t.start()
原文地址:https://www.cnblogs.com/while-number/p/9642167.html