博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python并发编程04/多线程
阅读量:5262 次
发布时间:2019-06-14

本文共 6858 字,大约阅读时间需要 22 分钟。

目录

Python并发编程04/多线程

1.生产消费者模型

#编程思想,模型,设计模式,理论等等,都是交给你一种编程的方法,以后你遇到类似的情况,套用即可.生产者消费者模型三要素:#   生产者: 产生数据的#   消费者: 接收数据做进一步处理的#   容器: 盆(队列)队列容器的作用:#起到缓冲的作用,平衡生产力与消费力,解耦.# from multiprocessing import Process# from multiprocessing import Queue# import time# import random## def producer(q,name):#     for i in range(1,6):#         time.sleep(random.randint(1,2))#         res = f'{i}号包子'#         q.put(res)#         print(f'生产者{name} 生产了{res}')### def consumer(q,name):#     while 1:#         try:#             food = q.get(timeout=3)#             time.sleep(random.randint(1, 3))#             print(f'\033[31;0m消费者{name} 吃了{food}\033[0m')#         except Exception:#             return## if __name__ == '__main__':#     q = Queue()#     p1 = Process(target=producer,args=(q,'小白'))#     p2 = Process(target=consumer,args=(q,'小黑'))#     p1.start()#     p2.start()

2.线程的理论知识

2.1什么是线程

#一条流水线的工作流程.#进程: 在内存中开启一个进程空间,然后将主进程的所有的资源数据复制一份,然后调用cpu去执行这些代码.#之前的描述不够具体:#开启一个进程: #在内存中开启一个进程空间,然后将主进程的所有的资源数据复制一份,然后调用线程去执行代码***进程是资源单位, 线程是执行单位.标准描述开启一个进程:    开启一个进程:进程会在内存中开辟一个进程空间,将主进程的资料数据全部复制一份,线程会执行里面的代码.

2.2线程vs进程

#1. 开启进程的开销非常大,比开启线程的开销大很多.#2. 开启线程的速度非常快.要快几十倍到上百倍.#3. 同一进程线程与线程之间可以共享数据,进程与进程之间需借助队列等方法实现通信.

2.3线程的应用

#1. 并发: 一个cpu 看起来像是同时执行多个任务.#   单个进程开启三个线程.并发的执行任务.#   开启三个进程并发的执行任务.#   文本编辑器:#      1. 输入文字.#      2. 在屏幕上显示.#      3. 保存在磁盘中.##   开启多线程就非常好了: #       数据共享, 开销小,速度快.#主线程子线程没有地位之分,但是,一个进程谁在干活? 一个主线程在干活,当干完活了,你得等待其他线程干完活之后,才能结束本进程.

3.开启进程的两种方式

3.1第一种方式

# from threading import Thread# import time## def task(name):#     print(f'{name} is running')#     time.sleep(1)#     print(f'{name} is gone')## if __name__ == '__main__':##     t1 = Thread(target=task,args=('二狗',))#     t1.start()#     print('===主线程')  # 线程是没有主次之分的.

3.2第一种方式

# from threading import Thread# import time## class MyThread(Thread):##     def __init__(self,name,l1,s1):#         super().__init__()#         self.name = name#         self.l1 = l1#         self.s1 = s1#     def run(self):#         print(f'{self.name} is running')#         time.sleep(1)#         print(f'{self.name} is gone')## if __name__ == '__main__':#     t1 = MyThread('二狗', [1,2,3], '180')#     t1.start()#     print('=====主线程')

4.线程vs进程的代码对比

4.1开启速度对比

多进程

# from threading import Thread# from multiprocessing import Process# import os## def work():#     print('hello')## if __name__ == '__main__':#     #在主进程下开启线程#     t=Process(target=work)#     t.start()#     print('主线程/主进程')

多线程

# from threading import Thread# import time## def task(name):#     print(f'{name} is running')#     time.sleep(1)#     print(f'{name} is gone')### if __name__ == '__main__':##     t1 = Thread(target=task,args=('二狗',))#     t1.start()#     print('===主线程')  # 线程是没有主次之分的.

4.2对比pid

进程

# from multiprocessing import Process# import time# import os# def task(name):#     print(f'子进程: {os.getpid()}')#     print(f'主进程: {os.getppid()}')## if __name__ == '__main__':##     p1 = Process(target=task,args=('二狗',))  # 创建一个进程对象#     p2 = Process(target=task,args=('二狗',))  # 创建一个进程对象#     p1.start()#     p2.start()#     print(f'==主{os.getpid()}')

线程

# from threading import Thread# import os## def task():#     print(os.getpid())## if __name__ == '__main__':##     t1 = Thread(target=task)#     t2 = Thread(target=task)#     t1.start()#     t2.start()#     print(f'===主线程{os.getpid()}')

4.3同一个进程内线程共享内部数据

# from threading import Thread# import os## x = 3# def task():#     global x#     x = 100## if __name__ == '__main__':##     t1 = Thread(target=task)#     t1.start()#     t1.join()#     print(f'===主线程{x}')同一进程内的资源数据对于这个进程的多个线程来说是共享的.

5.线程的其他方法

# from threading import Thread# from threading import currentThread# from threading import enumerate# from threading import activeCount# import os# import time## def task():#     # print(currentThread())#     time.sleep(1)#     print('666')# if __name__ == '__main__':##     t1 = Thread(target=task,name='线程1')#     t2 = Thread(target=task,name='线程2')#     # name 设置线程名#     t1.start()#     t2.start()#     # time.sleep(2)#     # print(t1.isAlive())  # 判断线程是否活着#     # print(t1.getName())  # 获取线程名#     # t1.setName('子线程-1')#     # print(t1.name)  # 获取线程名  ***##     # threading方法#     # print(currentThread())  # 获取当前线程的对象#     # print(enumerate())  # 返回一个列表,包含所有的线程对象#     print(activeCount())  # ***#     print(f'===主线程{os.getpid()}')

6.join与守护线程

6.1join

join: 阻塞 告知主线程要等待我子线程执行完毕之后再执行主线程# from threading import Thread# import time## def task(name):#     print(f'{name} is running')#     time.sleep(1)#     print(f'{name} is gone')## if __name__ == '__main__':#     start_time = time.time()#     t1 = Thread(target=task,args=('二狗',))#     t2 = Thread(target=task,args=('二狗1',))#     t3 = Thread(target=task,args=('二狗2',))##     t1.start()#     t1.join()#     t2.start()#     t2.join()#     t3.start()#     t3.join()##     print(f'===主线程{time.time() - start_time}')  # 线程是没有主次之分的.

6.2守护线程

# from threading import Thread# import time## def sayhi(name):#     print('你好!')#     time.sleep(2)#     print('%s say hello' %name)## if __name__ == '__main__':#     t = Thread(target=sayhi,args=('egon',))#     # t.setDaemon(True) #必须在t.start()之前设置#     t.daemon = True#     t.start()  # 线程的开启速度要跟进程开很多##     print('主线程')
# from threading import Thread# import time## def foo():#     print(123)  # 1#     time.sleep(1)#     print("end123")  # 4## def bar():#     print(456)  # 2#     time.sleep(3)#     print("end456")  # 5## t1=Thread(target=foo)# t2=Thread(target=bar)## t1.daemon=True# t1.start()# t2.start()# print("main-------")  # 3结果:123456main-------end123end456
守护线程 等待非守护子线程以及主线程结束之后,结束.# from threading import Thread# import time## def foo():#     print(123)  # 1#     time.sleep(3)#     print("end123")  # 4## def bar():#     print(456)  # 2#     time.sleep(1)#     print("end456")  # 5## t1=Thread(target=foo)# t2=Thread(target=bar)## t1.daemon=True# t1.start()# t2.start()# print("main-------")  # 3

7.互斥锁

# from threading import Thread# import time# import random# x = 100## def task():#     global x#     temp = x#     time.sleep(random.randint(1, 3))#     temp = temp - 1#     x = temp### if __name__ == '__main__':#     l1 = []#     for i in range(100):#         t = Thread(target=task)#         l1.append(t)#         t.start()##     for i in l1:#         i.join()#     print(f'主线程{x}')
多个任务公抢一个数据,保证数据的安全的目的,要让其串行# from threading import Thread# from threading import Lock# import time# import random# x = 100## def task(lock):##     lock.acquire()#     # time.sleep(random.randint(1,2))#     global x#     temp = x#     time.sleep(0.01)#     temp = temp - 1#     x = temp#     lock.release()### if __name__ == '__main__':#     mutex = Lock()#     l1 = []#     for i in range(100):#         t = Thread(target=task,args=(mutex,))#         l1.append(t)#         t.start()##     for i in l1:#       i.join()#     print(f'主线程{x}')

转载于:https://www.cnblogs.com/liubing8/p/11403483.html

你可能感兴趣的文章
poj2255Tree Recovery【二叉树重构】
查看>>
tcpcopy 流量复制工具
查看>>
vue和react的区别
查看>>
第十一次作业
查看>>
负载均衡策略
查看>>
微信智能开放平台
查看>>
ArcGIS Engine 中的绘制与编辑
查看>>
Oracle--通配符、Escape转义字符、模糊查询语句
查看>>
c# 文件笔记
查看>>
第一页 - 工具的使用(webstorm)
查看>>
Linux 进程资源用量监控和按用户设置进程限制
查看>>
IE浏览器整页截屏程序(二)
查看>>
D3.js 之 d3-shap 简介(转)
查看>>
制作满天星空
查看>>
类和结构
查看>>
CSS3选择器(二)之属性选择器
查看>>
adidas crazylight 2018 performance analysis review
查看>>
typeset shell 用法
查看>>
python 之 循环语句
查看>>
心得25--JDK新特性9-泛型1-加深介绍
查看>>