进程线程

1.操作系统帮助开发者操作硬件

2.程序员写好代码在操作系统上运行(依赖解释器)

线程的基本使用
def func(arg):

  print(arg)
t = threading.Thread(target=func,args=(11,))

t.start()  开始就绪

print(111)

主线程默认等子线程执行完毕

t = threading.Thread(target=func,args=(11,))

t.setDaemon(True)

t.start()  主线程不再等子线程,主线程终止则所有线程终止

join()  开发者可以控制主线程等待子线程(最多等待时间)

t.start()

t.join()  主线程等着,等到子线程执行完毕,才可以继续往下走

t.join(2)  子线程最多等两秒

lock = threading.RLock()

lock.acquire()  加锁,此区域的代码同一时刻只能有一个线程执行

lock.release()  释放锁

 

Python 的 GIL锁

  python内置的一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个线程可以被CPU调度

为什么有这把GIL锁

  Python语言的创始人在开发这门语言是,目的快速把语言开发出来,如果加上GIL锁,切换时按照100条字节指令来进行线程间的切换(编写起来简单)

为什么要加GIL锁    为了线程安全

  非线程安全

  控制一段代码

进程和线程的区别

  线程是CPU工作的最小单元

  进程为线程提供一个资源共享的空间  /是CPU资源分配的最小单元

  一个进程中可以有多个线程

  对于python来说它的进程和线程和其他语言有差异,是GIL锁,GIL锁保证一个进程中同一时刻只有线程被CPU调度

  

IO操作不占用CPU

  

进程和线程的使用准则

  计算密集型:多进程

  IO密集型:多线程

锁:Lock  一次锁

线程安全,多线程操作时,内部会让所有线程排队处理

RLock  支持多锁锁解(一次放一个)递归锁

lock = threading.BoudedSemaphore(一次放N个) 信号量

Condition(一次放x个,动态的)

Event(一次放所有)

ct = threading.current_thread()  获取当前线程

ct.getName()  获取名字

线程池

只有python3中有

threading,local  为每一个线程开辟空间,存取数据

import multiprocessing

multiprocessing.Queue()  进程间数据共享

 进程池/线程池

import time

from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

def task(arg):
  time.sleep(2)
  print(arg)

pool = ThreadPoolExeccutor(5)  限制一次五个线程#线程:ProcessPoolExecutor(5)  Windows需要加上 if __name__ == '__main__':

for i in range(10)        进程建议几核就几个进程

  pool.submit(task,i)

IO多路复用

I  Input  O  Output  IO多路复用可以监听所有的IO请求的状态。socket,cmd终端

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

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

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

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

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

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

用到的:IO多路复用 + socket非阻塞

client.setblocking(False)   #非阻塞

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

非阻塞:不等待  比如:创建socket对某个地址进行connect,获取接收数据recv时默认都会等待,连接成功后或接受到数据时,才会执行后续操作,如果设置setblocking(False),以上两个过程就不在等待,但是会报BlockingIOError的错误,只要捕获即可

   异步:执行完某个任务后,自动执行回调函数或自动执行某些操作(通知)   比如:做爬虫中向某个地址baidu.com发送请求,当请求执行完成之后自动执行回调函数

同步阻塞

阻塞:等

同步:按照顺序逐步执行

已经实现的模块:Twisted   基于事件循环实现的异步非阻塞框架

提高并发的方案:

  多进程

  多线程

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

协程  greenlet

协程是微线程,对一个线程进行分片,使得线程在代码块之间进行来回切换,而不是逐步执行

import greenlet
def f1():
print(11)
gr2.switch()
print(22)
gr2.switch()

def f2():
print(33)
gr1.switch()
print(44)

gr1 = greenlet.greenlet(f1)
gr2 = greenlet.greenlet(f2)
gr1.switch()
 

哈哈

单纯的协程无用

协程 + 遇到IO就切换  pip3 install gevent

from gevent import monkey
monkey.patch_all()
import requests
import gevent

def get_page(url):
ret = requests.get(url)
print(url,ret.content)

gevent.joinall([
gevent.spawn(get_page,'https://www.python.org/'),#协程
gevent.spawn(get_page,'https://www.yahoo.com/'),#协程
gevent.spawn(get_page,'https://github.com/')#协程
])

haha

1.什么是协程?

协程也可以成为“微线程”,就是开发者控制线程执行流程,控制先执行某段代码然后在切换到另外函数执行代码。。。来回切换

遇到switch就切换

2.协程可以提高并发吗?
协程自己本身无法实现并发(甚至性能会降低)

协程 + IO切换 性能提高

3.进程,线程,协程 的区别?

4.单线程提供并发:

  协程 + IO切换:gevent

  基于时间循环的异步非阻塞框架:Twisted

原文地址:https://www.cnblogs.com/nice777/p/11100423.html