进程:最小的数据单元

线程:最小的执行单元

一:

1:线程1

import threading #线程
import time
def Music():
print("Listen Music Begin %s" %time.ctime())
time.sleep()
print("Listen Music End %s" %time.ctime())
def Game():
print("Play Game Begin %s" %time.ctime())
time.sleep()
print("Play Game End %s" %time.ctime())
if __name__ == '__main__':
t1 = threading.Thread(target=Music)
t1.start()
t2 = threading.Thread(target=Game)
t2.start() print("ending......")

实例1

import threading #线程
import time
def Music():
print("Listen Music Begin %s" %time.ctime())
time.sleep(3)
print("Listen Music End %s" %time.ctime())
def Game():
print("Play Game Begin %s" %time.ctime())
time.sleep(5)
print("Play Game End %s" %time.ctime())
if __name__ == '__main__':
t1 = threading.Thread(target=Music)
t1.start()
t2 = threading.Thread(target=Game)
t2.start()
t1.join()
t2.join()
print("ending......")

线程join

import threading #线程
import time
def Music(musicName):
print("Listen Music【%s】 Begin %s" %(musicName,time.ctime()))
time.sleep(3)
print("Listen Music【%s】 End %s" %(musicName,time.ctime()))
def Game(playName):
print("Play Game【%s】 Begin %s" %(playName,time.ctime()))
time.sleep(5)
print("Play Game【%s】 End %s" %(playName,time.ctime()))
if __name__ == '__main__':
t1 = threading.Thread(target=Music,args=("My Heart Will Go On",))
t2 = threading.Thread(target=Game,args=("植物大战僵尸",))
threads=[]
threads.append(t1)
threads.append(t2)
for t in threads:
t.start();
print("ending......")

线程参数

import threading #线程
import time
def Music(musicName):
print("Listen Music【%s】 Begin %s" %(musicName,time.ctime()))
time.sleep(3)
print("Listen Music【%s】 End %s" %(musicName,time.ctime()))
def Game(playName):
print("Play Game【%s】 Begin %s" %(playName,time.ctime()))
time.sleep(5)
print("Play Game【%s】 End %s" %(playName,time.ctime()))
t1 = threading.Thread(target=Music,args=("My Heart Will Go On",))
t2 = threading.Thread(target=Game,args=("植物大战僵尸",))
threads=[]
threads.append(t1)
threads.append(t2)
if __name__ == '__main__':
t2.setDaemon(True)
for t in threads:
t.start();
print("ending......")

守护线程

# 多线程为什么要使用锁?
# 多线程共用一个数据集,不使用可能会造成数据不准确
#1:引入多线程模块
import threading
import time
# 2:定义一个变量(数据集)
num=100
# 3:定义一个方法,操作全局变量
def sub():
global num
temp = num
time.sleep(0.001)
num=temp-1
# 4:创建多个线程
ts=[]
for i in range(0,100):
t=threading.Thread(target=sub)
t.start()
ts.append(t)
for t in ts:
t.join()
print(num)

未加锁,数据结果有误

# 多线程为什么要使用锁?
# 多线程共用一个数据集,不使用可能会造成数据不准确
#1:引入多线程模块
import threading
import time
# 2:定义一个变量(数据集)
num=100
# 3:定义一个方法,操作全局变量
# 5:创建锁
lock=threading.Lock()
def sub():
global num
# 5.1 加锁
lock.acquire()
temp = num
time.sleep(0.001)
num=temp-1
# 5.2 释放锁
lock.release()
# 4:创建多个线程
ts=[]
for i in range(0,100):
t=threading.Thread(target=sub)
t.start()
ts.append(t)
for t in ts:
t.join() print(num)

同步锁

#当两个锁之间出现递归调用,彼此之间相互等待,就会出现死锁
#线程的另一种实现方式(通过自定义类)
#1:引入threading、time
import threading
import time
# 定义两个锁
lockA=threading.Lock()
lockB=threading.Lock()
#3:定义一个线程(线程中存在两个方法,存在递归调用)
class MyThread(threading.Thread):
#定义两个方法
def actionA(self):
# 获取A锁
lockA.acquire()
print(self.name,"gotA",time.ctime())
time.sleep(1)
#然后再获取B锁
lockB.acquire()
print(self.name,"gotB",time.ctime())
time.sleep(2)
# 先释放B锁,
lockB.release()
# 后释放A锁
lockA.release()
def actionB(self):
# 获取B锁
lockB.acquire()
print(self.name, "gotB", time.ctime())
time.sleep(1)
# 然后再获取A锁
lockA.acquire()
print(self.name, "gotA", time.ctime())
time.sleep(2)
# 先释放A锁,
lockA.release()
# 后释放B锁
lockB.release()
#实现run方法
def run(self):
self.actionA()
self.actionB() # 4:创建多个线程
for i in range(0,5):
t=MyThread()
t.start()

死锁现象

#当两个锁之间出现递归调用,彼此之间相互等待,就会出现死锁
#线程的另一种实现方式(通过自定义类)
#1:引入threading、time
import threading
import time
# 定义两个锁
lockA=threading.Lock()
lockB=threading.Lock() lockR=threading.RLock() #把两个锁替换成一个RLock,内部通过计数器实现
#3:定义一个线程(线程中存在两个方法,存在递归调用)
class MyThread(threading.Thread):
#定义两个方法
def actionA(self):
# 获取A锁
# lockA.acquire()
lockR.acquire()
print(self.name,"gotA",time.ctime())
time.sleep(1)
#然后再获取B锁
# lockB.acquire()
lockR.acquire()
print(self.name,"gotB",time.ctime())
time.sleep(2)
# 先释放B锁,
# lockB.release()
lockR.release()
# 后释放A锁
# lockA.release()
lockR.release()
def actionB(self):
# 获取B锁
# lockB.acquire()
lockR.acquire()
print(self.name, "gotB", time.ctime())
time.sleep(1)
# 然后再获取A锁
# lockA.acquire()
lockR.acquire()
print(self.name, "gotA", time.ctime())
time.sleep(2)
# 先释放A锁,
# lockA.release()
lockR.release()
# 后释放B锁
lockR.release()
# lockB.release()
#实现run方法
def run(self):
self.actionA()
self.actionB() # 4:创建多个线程
for i in range(0,5):
t=MyThread()
t.start()

递归锁,解决死锁

# 1:引入包
import threading
import time
# 2:创建同步锁
event = threading.Event()
#3:创建线程对象
class Boss(threading.Thread):
def run(self):
print("大家加班")
event.set()
time.sleep(5)
print("下班了")
event.set()
class Worker(threading.Thread):
def run(self):
event.wait()
print("不加班,不加班")
time.sleep(1)
event.clear()
event.wait()
print("Oh Yeah")
# 4:创建线程对象,并放入到线程集合中
ts=[]
t=Boss()
ts.append(t)
for i in range(0,5):
ts.append(Worker())
for t in ts:
t.start()

同步锁

# 信号量类似于停车场,一次只能处理n个线程
# 1:导包
import threading,time
# 2:设置信号量
semaphore = threading.Semaphore(5)
# 3:创建线程对象
class MyThread(threading.Thread):
def run(self):
if semaphore.acquire():
print(self.name)
time.sleep(3)
semaphore.release() # 4:创建线程对象
for i in range(0,20):
t=MyThread()
t.start()

信号量

# 队列:多线程,线程安全
# 1:引包
import queue,time
# 2:创建对象
q=queue.Queue(3) #3表示队列的总容量为3、默认为先进先出类型
# 3:常用的方法
q.put("#3333") #添加数据
q.put({"ab":"cd"}) print(q.get()) #获取数据
print(q.qsize()) #获取队列的长度
print(q.empty()) #判断是否为空
print(q.full()) #判断是否已满
print(q.task_done()) #每对队列进行一次操作以后就会返回True
print(q.join()) #task_done 对应的就是join

队列的常见属性

# 通过队列,设置一个生产者消费者的开发模型
# 1:引包
import threading,queue,time,random
# 2:定义队列
que=queue.Queue()
# 3:定义两个生产者、消费者的类
def Producer(name):
countBaoZi=1;
while countBaoZi <= 10:
# print("包子数量小于10,开始生产包子")
time.sleep(random.randrange(1,3))
que.put(countBaoZi)
print("生产者:%s,生产了【包子%s】" % (name, countBaoZi))
countBaoZi = countBaoZi + 1
def Consumer(name):
countBaoZi=1
while countBaoZi<=10:
time.sleep(random.randrange(1,4))
if que.empty():
print("老板没包子了")
else:
print("现在还有%s个包子" % que.qsize())
curBaoZi = que.get()
print("消费者:%s,吃了包子【%s】" % (name, curBaoZi)) # 4:创建多个线程
producerA = threading.Thread(target=Producer,args=("A大厨",))
consumerA = threading.Thread(target=Consumer,args=("A君",))
consumerB = threading.Thread(target=Consumer,args=("B君",)) producerA.start()
consumerA.start()
consumerB.start()

队列-线程 生产者、消费者模式

# 通过队列,设置一个生产者消费者的开发模型
# 升级版,包子吃了以后,还需要再去检查一下,有没有包子if que.empty() 这样浪费时间,
# 应该是:吃完就告诉老板直接生产,生产好了再通知客户去吃
# 1:引包
import threading,queue,time,random
# 2:定义队列
que=queue.Queue()
# 3:定义两个生产者、消费者的类
def Producer(name):
countBaoZi=1;
while countBaoZi <= 10:
time.sleep(random.randrange(1,3))
que.put(countBaoZi)
print("生产者:%s,生产了【包子%s】" % (name, countBaoZi))
countBaoZi = countBaoZi + 1
que.join() def Consumer(name):
countBaoZi=1
while countBaoZi<=10:
time.sleep(random.randrange(1,4))
print("现在还有%s个包子" % que.qsize())
curBaoZi = que.get()
time.sleep(1)
print("消费者:%s,吃了包子【%s】" % (name, curBaoZi))
que.task_done() # 4:创建多个线程
producerA = threading.Thread(target=Producer,args=("A大厨",))
consumerA = threading.Thread(target=Consumer,args=("A君",))
consumerB = threading.Thread(target=Consumer,args=("B君",)) producerA.start()
consumerA.start()
consumerB.start()

队列-线程 生产消费2

二 进程

# 1:导包
import time
from multiprocessing import Process
# 2:创建进程对象集合
pros=[]
# 3:定义方法
def music(musicName):
print("开始播放:%s.%s" %(musicName,time.ctime()))
time.sleep(2)
print("播放结束:%s.%s" %(musicName,time.ctime()))
def play(gameName):
print("开始打:%s.%s" %(gameName,time.ctime()))
time.sleep(5)
print("游戏结束:%s.%s" %(gameName,time.ctime()))
if __name__ == '__main__':
# 4:创建进行对象
mu=Process(target=music,args=("My Heart Will Go On",))
mu.start()
mg=Process(target=play,args=("植物大战僵尸",))
mg.start()

进程

# 1:导包
import time
from multiprocessing import Process
# 2:创建进程对象集合
pros=[]
# 3:定义方法
def music(musicName):
print("开始播放:%s.%s" %(musicName,time.ctime()))
time.sleep(2)
print("播放结束:%s.%s" %(musicName,time.ctime()))
def play(gameName):
print("开始打:%s.%s" %(gameName,time.ctime()))
time.sleep(5)
print("游戏结束:%s.%s" %(gameName,time.ctime()))
if __name__ == '__main__':
# 4:创建进行对象
mu=Process(target=music,args=("My Heart Will Go On",))
# 4.2:进程常用的属性和方法
#mu.join() #进程阻塞
mu.start() #开启进程
time.sleep(1)
mu.terminate() #结束进程
print(" 进程名称 %s, 进程编码 %s,"%(mu.name,mu.pid))

常用的属性和方法

进程之间的三种通讯方法

进程队列

# 1:导包
from multiprocessing import Process,Queue
import time
#2:定义一个方法,用于向队列中赋值
def putAction(q,n):
q.put(n*(n+1))
print("当前队列的id:",id(q)) if __name__ == '__main__':
# 3:创建一个队列
que=Queue()
print("main方法中队列的id:", id(que))
# 4:通过循环创建多个进程
for i in range(0,3):
p=Process(target=putAction,args=(que,i,))
p.start()
print(que.get())
print(que.get())
print(que.get())

通过进程队列实现数据通信

# 管道相当于生成两个连接对象,一个主进程使用,另外一个传递给子进程使用
# 1:导包
from multiprocessing import Process,Pipe
import time
# 2:定义函数
def ConnAction(conn):
# 获取传递过来的conn连接对象
print("准备发送消息,时间%s"%(time.ctime()))
conn.send("土豆土豆,我是地瓜,收到请回答")
time.sleep(2)
print("准备接收消息,时间%s"%(time.ctime()))
responInfo = conn.recv()
print(responInfo,time.ctime()) if __name__ == '__main__':
# 创建管道对象
par_conn,child_conn=Pipe()
# 创建进程
p=Process(target=ConnAction,args=(child_conn,))
p.start()
print("主进程,准备接收消息,%s"%(time.ctime()))
respons=par_conn.recv()
print(respons,time.ctime())
time.sleep(2)
print("主进程,准备发送消息,%s"%(time.ctime()))
par_conn.send("地瓜地瓜,我是土豆");

通过管道实现数据通信

# 1:导包
from multiprocessing import Process,Manager
#2:定义方法
def manaAction(d,l,n):
# 对字典进行操作
d[n]=""
d[""]=2
# 对列表进行操作
l.append(n)
if __name__ == '__main__':
# 创建Manager对象中的数据类型
with Manager() as manager:
d=manager.dict()
l=manager.list(range(5))
p_list=[]
# 创建进程
for i in range(0,5):
p=Process(target=manaAction,args=(d,l,i))
p.start()
p_list.append(p)
for res in p_list:
res.join()
print(d)
print(l)

通过Manager实现数据通信

# 1:导入包
from multiprocessing import Process,Lock
import time
#定义方法
def printPro(l,n):
with l:
print("Hello,World %s,%s"%(n,time.ctime()))
time.sleep(1) if __name__ == '__main__':
l=Lock()
for i in range(0, 5):
p = Process(target=printPro, args=(l,i,))
p.start()

进程锁

# 1:导包
from multiprocessing import Process,Pool
import time # 3:创建方法
def foo(i):
time.sleep(1)
print(i)
return i
# 4:创建回调方法
def bar(arg):
#回调方法在主函数中执行
print("hello,%s"%arg) if __name__ == '__main__':
# 2:创建进程池对象
pool = Pool(5)
for i in range(0,30):
pool.apply_async(func=foo,args=(i,),callback=bar)
pool.close()
pool.join()

进程池

三 协程

  协程是一种非抢占式程序,其本质是一个线程。

  优点:1:灭有切换消耗;2:没有锁的概念

  缺点:无法使用多核,但是可以通过多进程+协程弥补

# 通过yield来实现
# 1:导包
import time
#2:消费者
def Consumer(name):
print("准备开始吃包子")
while True:
newbaozi=yield
print("%s吃了包子%s"%(name,newbaozi))
#3:生产者
def Product():
r=con.__next__()
r2=con2.__next__()
baoziName=1
while True:
time.sleep(1)
print("生产者,生产了%s和%s包子"%(baoziName,baoziName+1))
con.send(baoziName)
con2.send(baoziName+1)
baoziName+=2
#主方法
if __name__ == '__main__':
#创建两个用户
con=Consumer("张三")
con2=Consumer("李四")
Product()

协程-yield

from greenlet import greenlet
def test1():
print(12)
gr2.switch()
print(34)
gr2.switch()
def test2():
print(56)
gr1.switch()
print(78)
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

协程-greenlet

# 1:导包
import gevent
import requests,time # 记录开始时间
start = time.time()
def f(url):
# print("Get:%s" %url)
reap=requests.get(url)
data=reap.text
print("%s网址上一共有%s字节"%(url,len(data)))
gevent.joinall([
gevent.spawn(f, 'https://www.python.org/'),
gevent.spawn(f, 'https://www.yahoo.com/'),
gevent.spawn(f, 'https://www.baidu.com/'),
gevent.spawn(f, 'https://www.sina.com.cn/'),
])
print("耗时",time.time()-start)
f('https://www.python.org/')
f('https://www.yahoo.com/')
f('https://www.baidu.com/')
f('https://www.sina.com.cn/')
print("耗时",time.time()-start)

协程-gevent

饮冰三年-人工智能-Python-20 Python线程、进程、线程的更多相关文章

  1. 饮冰三年-人工智能-Python-22 Python初识Django

    1:一个简单的web框架 # 导包 from wsgiref.simple_server import make_server #自定义个处理函数 def application(environ,st ...

  2. 饮冰三年-人工智能-Python-21 Python数据库MySql

    一:下载与安装 1:下载地址:https://dev.mysql.com/downloads/mysql/ 2:安装MySql 打开下载文件解压到指定文件目录.(我这里解压目录为D:\MySql\my ...

  3. 饮冰三年-人工智能-Python-19 Python网络编程

    Socket:套接字.作用:我们只需要安照socket的规定去编程,就不需要深入理解tcp/udp协议也可以实现 1:TCP协议 1.1  客户端服务端循环收发消息 # 1:引入stock模块(导包) ...

  4. 饮冰三年-人工智能-Python-10之C#与Python的对比

    1:注释 C# 中 单行注释:// 多行注释:/**/ python 中 单行注释:# 多行注释:“““内容””” 2:字符串 C#中 "" 用双引号如("我是字符串&q ...

  5. 饮冰三年-人工智能-linux-08 软件包管理(Python的安装)

    1:软件包存放的位置 media/CentOS_6.9_Final/Packages文件夹下 2.RPM就是Red Hat Package Manger(红帽软件包管理工具)的缩写. 2.1 常用的命 ...

  6. 饮冰三年-人工智能-Python-30 python开发中常见的错误

    1:触发条件:创建的实体类生成到数据库表时报错 报错信息:TypeError: __init__() missing 1 required positional argument: 'on_delet ...

  7. 饮冰三年-人工智能-Python-23 Python PyCharm 使用中常见的问题

    一:软件工具使用中遇到的问题 1:AttributeError: module 'pip' has no attribute 'main'问题 处理方法: a:找到JetBrains\PyCharm ...

  8. 饮冰三年-人工智能-Python-18Python面向对象

    1 类与实例对方法和属性的修改 class Chinese: # 这是一个Chinese的类 #定义一个类属性,又称为静态数据或者静态变量,相当于C#中的static country="Ch ...

  9. 饮冰三年-人工智能-Python-25 Django admin

    简介:一个关于后台数据库管理的工具 1:创建一个新的项目 2:设置models,并通过命令生成数据库表 from django.db import models class Book(models.M ...

随机推荐

  1. Python——assert(断言函数)

    一.断言函数的作用 python assert断言是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假.可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会 ...

  2. bootstrapValidator操作

    1.html中表单初始化 <script> //表单验证初始化 $('#wx_pay_account_form_id').bootstrapValidator({ message : 'T ...

  3. Django+Vue打造购物网站(六)

    商品详情页功能 商品详情页和CategoryViewSet类似,只需要多继承一个类(mixins.RetrieveModelMixin)就可以了 class GoodsListViewSet(mixi ...

  4. 2017-12-19python全栈9期第四天第二节之列表的增删查改之按切片删除

    #!/user/bin/python# -*- coding:utf-8 -*-li = ['zs','ls','ww','zl','xx']# del li[1:] #1到最后# print(li) ...

  5. Pandas系列(十三)-其他常用功能

    一.统计数据频率 1. values_counts pd.value_counts(df.column_name) df.column_name.value_counts() Series.value ...

  6. elk中fliebeat的配置文件

    fliebeat----> kafka的配置文件 # cat filebeat.yml|egrep -v "^$|^#"|grep -v "^ #" fi ...

  7. Python 文件读取

    1. 最基本的读文件方法: # File: readline-example-1.py file = open("sample.txt") while 1: line = file ...

  8. 1.1浅谈Spring(一个叫春的框架)

    如今各种Spring框架甚嚣尘上,但是终归还是属于spring的东西.所以在这里,个人谈一谈对spring的认识,笔者觉得掌握spring原理以及spring所涉及到的设计模式对我们具有极大的帮助.我 ...

  9. EF CodeFirst系列(2)---CodeFirst的数据库初始化

    1. CodeFirst的默认约定 1.领域类和数据库架构的映射约定 在介绍数据库的初始化之前我们需要先了解领域类和数据库之间映射的一些约定.在CodeFirst模式中,约定指的是根据领域类(如Stu ...

  10. tolua之wrap文件的原理与使用

    什么是wrap文件 每个wrap文件都是对一个c#类的包装,在lua中,通过对wrap类中的函数调用,间接的对c#实例进行操作. wrap类文件生成和使用的总体流程 生成一个wrap文件的流程 这部分 ...