From 79699a7cfbddf0c60dedcff45079a85630134594 Mon Sep 17 00:00:00 2001 From: diandian Date: Wed, 15 Nov 2023 14:55:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=20'Other'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Other/wr.md | 32 ++++ Other/多线程.md | 264 ++++++++++++++++++++++++++++++ Other/生产者消费者模型.md | 98 +++++++++++ 3 files changed, 394 insertions(+) create mode 100644 Other/wr.md create mode 100644 Other/多线程.md create mode 100644 Other/生产者消费者模型.md diff --git a/Other/wr.md b/Other/wr.md new file mode 100644 index 0000000..7183bd8 --- /dev/null +++ b/Other/wr.md @@ -0,0 +1,32 @@ +![img](https://diandiange.oss-cn-beijing.aliyuncs.com/20190619083502880.png) + +**Alan Cooper ——VB之父** + +![img](https://diandiange.oss-cn-beijing.aliyuncs.com/20190619083511331.png) + +**Bjarne Stroustrup——C++之父** + +![img](https://diandiange.oss-cn-beijing.aliyuncs.com/20190619083520777.png) + +**James Gosling——Java之父** + +![img](https://diandiange.oss-cn-beijing.aliyuncs.com/20190619083530693.png) + +**Rob Pike——GoLang之父** + +![img](https://diandiange.oss-cn-beijing.aliyuncs.com/20190619083539602.png) + +**Brendan Eich——JavaScript之父** + +![img](https://diandiange.oss-cn-beijing.aliyuncs.com/2019061908354975.png) + +**Rasmus Lerdorf——PHP之父** + +**头顶茂密程度:★★★** + +![img](https://diandiange.oss-cn-beijing.aliyuncs.com/20190619083558434.png) + +**Guido van Rossum——Python之父** + +![img](https://diandiange.oss-cn-beijing.aliyuncs.com/20190619083607110.png) + diff --git a/Other/多线程.md b/Other/多线程.md new file mode 100644 index 0000000..fc76427 --- /dev/null +++ b/Other/多线程.md @@ -0,0 +1,264 @@ +# 多任务介绍 +什么是多任务? +操作系统可以同时执行多个任务 + +现在的操作系统:windows mac linux unix +这些操作系统 都支持多任务 + +单核CPU如何实现多任务? +表面看,每个任务都是同时执行,实际上是每个任务在轮询着执行,只是因为CPU的调度太快,导致我们感觉像是所有任务都在同时执行 + +多核CPU如何实现多任务? +是真正实现了多个任务同时执行 + +并发:看上去一起执行,任务数大于CPU核心数 +并行:一起执行,任务数必须小于等于CPU核心数 + +实现多任务的方式: +1、多进程方式 +2、多线程方式 +3、协程方式 +4、多进程+多线程 + +### 没有多进程 + +```python +import time +def func(): + while True: + print("this is a process2") + time.sleep(1.5) +if __name__ == '__main__': + while True: + print("this is a process1") + time.sleep(1) + func() + +``` + +### multiprocessing 多进程 + +```python +from multiprocessing import Process +import time,os + +def func(str): + +#os.getpid 获取当前进程的进程号 + +#os.getppid 获取当前进程的父进程 + + while True: + print("this is process 2--%s--%s--%s"%(str,os.getpid(),os.getppid())) + time.sleep(1.5) + +if __name__ == '__main__': + print("父进程启动...--%s--%s"%(os.getpid(),os.getppid())) + # 创建子进程 + # target 说明进程的任务 + p = Process(target=func,args=("python",)) + # 启动进程 + p.start() + # 主进程中的 + while True: + print("this is a process 1--%s--%s"%(os.getpid(),os.getppid())) + time.sleep(1) + + +``` + +### 让父进程等待子进程结束之后父进程再结束 + +```python +from multiprocessing import Process +from time import sleep + +def func(): + print("子进程启动...") + sleep(3) + print("子进程结束...") + +if __name__ == '__main__': + print("父进程启动...") + p = Process(target = func) + p.start() + # sleep(1) + # 让父进程等待子进程结束之后父进程再结束 + # timeout 超时时间 父进程的等待时间 + p.join() + #执行后一直等待 + print("父进程结束...") +``` + +### 在子进程中修改全局变量 对父进程中的全局变量没有影响 + +```python +from multiprocessing import Process +num = 100 +def run1(): + print("孙子进程开始...") + print("孙子进程结束...%s"%(num)) + +def run(): + print("子进程开始...") + global num + num += 1 + print(num) + p = Process(target=run1) + p.start() + p.join() + print("子进程结束...") + +if __name__ == '__main__': + print("父进程开始...") + p = Process(target=run) + p.start() + p.join() + num += 2 + # 在子进程中修改全局变量 对父进程中的全局变量没有影响 + # 我们在创建子进程的时候 对全局变量做了一个备份 + # 子进程和父进程的Num是两个完全不同的变量 + # 所有进程对全局变量的修改 都不会影响其它进程 + print("父进程结束...%d"%(num)) + +``` + +### 进程池 + +```python +from multiprocessing import Pool,Process +import time,random +def foo(): + print("孙子进程开始...") + print("孙子进程结束...") +def func(__name__): + print("子进程%s启动..."%(__name__)) + start = time.time() + time.sleep(random.choice([1,2,3])) + end = time.time() + print("子进程%s结束...耗时%.2f"%(__name__,end - start)) + +if __name__ == '__main__': + print("父进程开始...") + # 创建进程池 + # 如果没有参数 默认大小为自己电脑的CPU核心数 + # 表示可以同时执行的进程数量 + pp = Pool(2) + for i in range(4): + # 创建进程,放入进程池统一管理 + pp.apply_async(func,args=(i,)) + # 在调用join之前必须先关掉进程池 + # 进程池一旦关闭 就不能再添加新的进程了 + pp.close() + # 进程池对象调用join,会等待进程池中所有的子进程结束之后再结束父进程 + pp.join() + print("父进程结束...") + +``` + + + +# 多线程: + +在一个进程内部,要同时干很多事,就需要同时执行多个子任务 +那么我们把进程内的这些子任务叫做线程 + +线程的内存空间是共享的 每个线程都共享同一个进程的资源 + +模块: +1、_thread模块 低级模块 +2、threading模块 高级模块 对_thread模块进行了封装 +""" +### 创建线程 + +```python +import threading,time + +def run(num): + print("子线程%s开始..."%(threading.current_thread().__name__)) + time.sleep(2) + print(num) + time.sleep(2) + # current_thread 返回一个当前线程的实例 + print("子线程%s结束..."%(threading.current_thread().__name__)) +if __name__ == '__main__': + print("主线程%s启动..."%(threading.current_thread().__name__)) + # 创建子线程 + t = threading.Thread(target = run,args = (1,)) + t.start() + t.join() + print("主线程%s结束..."%(threading.current_thread().__name__)) + +``` + +### 多线程共享资源 + +```python +import threading + +num = 0 +var = 0 +def run(n): + global num + for i in range(1000000): + num += n + num -= n +def run1(n): + global var + for i in range(100): + var += n + var -= n + +if __name__ == '__main__': + t1 = threading.Thread(target=run,args=(6,)) + t2 = threading.Thread(target=run,args=(9,)) + t3 = threading.Thread(target=run,args=(5,)) + t3.start() + t1.start() + t2.start() + t1.join() + t2.join() + t3.join() + print("num = %s"%(num)) + +``` + +### 互斥锁 + +```python +import threading + +创建锁对象 + +lock = threading.Lock() +num = 0 + +def run(n): + global num + for i in range(1000000): + # 加锁 为了确保下面代码只能由一个线程从头到尾的执行 + # 会阻止多线程的并发执行,所以效率会大大降低 + """ + lock.acquire() + try: + num = num - n + num = num + n + finally: + # 解锁 + lock.release() + """ + with lock: + num = num + n + num = num - n + +if __name__ == '__main__': + t1 = threading.Thread(target=run,args=(6,)) + t2 = threading.Thread(target=run,args=(9,)) + t1.start() + t2.start() + t1.join() + t2.join() + print("num = %s"%(num)) + +``` + diff --git a/Other/生产者消费者模型.md b/Other/生产者消费者模型.md new file mode 100644 index 0000000..fb418a2 --- /dev/null +++ b/Other/生产者消费者模型.md @@ -0,0 +1,98 @@ +# 生产者消费者模型 + +## 概念 + +``` + 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。 +``` + +``` + 生产者直接将商品交给消费者,如果消费者承受能力不佳,就会发生崩溃,这个时候需要另一个角色--仓库。 + 生产者 --- 仓库 --- 消费者 +优点 + 解耦–生产者-消费者之间不直接通信,降低了耦合度。 + 并发 + +``` + +测试代码 + +```python +import time +import random +from multiprocessing import Queue,Process + +def consumer(name,q): + while True: + res=q.get() + if res is None:break + time.sleep(random.randint(1,3)) + print('\033[40m 食客%s 开始吃%s'%(name,res)) + +def producer(name,q): + for i in range(5): + time.sleep(random.randint(1,2)) + res='炒粉%s'%i + q.put(res) + print('\033[40m 厨师%s 生产了%s'%(name,res)) + +if __name__ == '__main__': + q=Queue()#一个队列 + + p1=Process(target=producer,args=('老刘',q)) + c1=Process(target=consumer,args=('小明',q)) +# c2=Process(target=consumer,args=('小红',q)) + + p1.start() + c1.start() +# c2.start() + p1.join() + q.put(None) + +``` + + + +# 发布者订阅者模型 + +测试代码 + +```python +发布者 +#!/usr/bin/env python +#coding:utf-8 +import redis +pool=redis.ConnectionPool(host='127.0.0.1', + port=6379,db=0, + password='123456') +r=redis.StrictRedis(connection_pool=pool) +while True: + msg=input("publish: >>") + if msg=="over": + print("停止发布") + break + r.publish('spub',msg) + +订阅者 +#!/usr/bin/env python +import redis +pool=redis.ConnectionPool(host='127.0.0.1', + port=6379,db=0, + password='123456') +r=redis.StrictRedis(connection_pool=pool) +p=r.pubsub() +p.subscribe("spub","cctv1") +for item in p.listen(): + print("Listen on channel : %s "%item['channel'].decode()) + if item['type']=='message': + data=item['data'].decode() + print("From %s get message : %s"%(item['channel'].decode(),item['data'].decode())) + if item['data']=='over': + print(item['channel'].decode(),'停止发布') + break +p.unsubscribe('spub') +print("取消订阅") + + +``` +