饮冰三年-人工智能-Python-20 Python线程

Posted 逍遥小天狼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了饮冰三年-人工智能-Python-20 Python线程相关的知识,希望对你有一定的参考价值。

进程:最小的数据单元

线程:最小的执行单元

一:

1:线程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()

    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饮冰三年-人工智能-Python-11之HelloWor

饮冰三年-人工智能-Python-38 爬虫之并发

饮冰三年-人工智能-Python-22 Python初始Django

饮冰三年-人工智能-Python-12之利其器pycharm

饮冰三年-人工智能-linux-02 初始Linux

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