python 多线程

Posted 起个名字真难1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 多线程相关的知识,希望对你有一定的参考价值。

(一)基础概念 线程:是程序执行流的最小单元(线程内部可开线程)、每一个程序都至少有一个线程、线程共享统一进程中的所有资源。

进程:是最小的资源单元(内存资源的分配与调度)线程共享进程中的资源,(每个进程中至少有一个线程(QQ360))

并发:是指系统具有执行多个任务(动作)的能力 并行:是指系统具同一时刻进行多个任务(动作)的能力(是并发子集)

线程与进程关系:一个程序至少有一个进程、每个进程中至少有 一个线程

(1)线程的创建(threading接口)

(1)线程的创建(threading接口)
1.自己创建线程
# sampleOne
import threading
import time
def Hi(name):
    print("Hello %s" %name)
    time.sleep(3)
if __name__=="__main__":
    t1 = threading.Thread(target=Hi,args=("萌萌",))
    t1.start()
    t2 = threading.Thread(target=Hi, args=("蒙蒙",))
    t2.start()
    print("end")

  

2)线程的调用方式

2.创建线程类继承threading.Thread类下的方法
class Mythread(threading.Thread):
    def __init__(self, num):
        # threading.Thread.__init__(self)
        super().__init__()
        self.num = num
    def run(self):
        # music1()
        # game1()
        print("start num %d" % self.num)
if __name__ == "__main__":
    t1 = Mythread(1)
    t2 = Mythread(2)
    t1.start()
    t2.start()

(3)线程阻塞join方法

join:子线程完成之前主线程一直阻塞‘‘‘
def music():
    print("begin to listen %s" %time.ctime())
    time.sleep(3)
    print("stop to listen %s" % time.ctime())
def game():
    print("begin to game %s" % time.ctime())
    time.sleep(5)
    print("stop to game %s" % time.ctime())
if __name__ == "__main__":
    t1 = threading.Thread(target=music, )
    t2 = threading.Thread(target=game, )
    t1.start()
    t2.start()
    # t1.join()
    t2.join()
  print("over end ")

  

(4)线程的守护 setDaemon

‘‘‘setDaemon:线程守护、子线程跟随主线程一起退‘‘‘
def music1():
    print("begin to listen %s" %time.ctime())
    time.sleep(3)
    print("stop to listen %s" % time.ctime())
def game1():
    print("begin to game %s" % time.ctime())
    time.sleep(5)
    print("stop to game %s" % time.ctime())
if __name__ == "__main__":
    t1 = threading.Thread(target=music1, )
    t2 = threading.Thread(target=game1, )
    t2.setDaemon(True)
    t1.start()
    t2.start()

 (5)线程锁与递归锁、结果不是想要的、多个线程操作同一个对象是引发数据安全、只能借助线程锁threading.Lock()

# 开100个线程、每个线程对同一个数递减1
import time
import threading
def sub():
    global num
    temp = num
    time.sleep(0.01)
    num = temp-1
if __name__=="__main__":
    num=100
    for i in range(100):
        t = threading.Thread(target=sub)
        t.start()
    t.join()

  ‘‘‘针对线程安全问题创建线程同步锁‘、‘‘输出结果为0、是想要的结果、但有些情况锁也会带来负面的影响

def sub1():
    global num
    lock.acquire()
    temp = num
    time.sleep(0.001)
    num = temp-1
    lock.release()
if __name__ =="__main__":
    num=100
    lock=threading.Lock()
    for i in range(100):
        t = threading.Thread(target=sub1)
        t.start()
    t.join()
    print(num)

  死锁

class Mythread(threading.Thread):
    def actionA(self):
        A.acquire()
        print(self.name, "got A", time.ctime())
        B.acquire()  
        print(self.name, "got B", time.ctime())
        B.release()  
        A.release() 
    def actionB(self):
        B.acquire()
        print(self.name, "got B", time.ctime())
        A.acquire()
        print(self.name, "got A", time.ctime())
        A.release()
        B.release()
    def run(self):
        self.actionA()
        self.actionB()
if __name__ == "__main__":
    L = []
    A=threading.RLock()
    B=threading.RLock()
    for i in range(5):
        t = Mythread()
        t.start()
        L.append(t)
    for t in L:
        t.join()
    print("ending>>>>>>>>>>")

 (5)递归锁RLock()解决死锁问题  

创建一把递归锁、替换上面的所有锁 r_lock=threading.RLock()

class Mythread(threading.Thread):
    ‘‘‘递归锁 解决死锁‘‘‘
    def actionA(self):
        r_lock.acquire()  # count=1
        print(self.name, "got A", time.ctime())
        r_lock.acquire()  # 锁中锁 count=2
        print(self.name, "got B", time.ctime())
        r_lock.release()  # count = 1
        r_lock.release()  # count = 0
    def actionB(self):
        r_lock.acquire()
        print(self.name, "got B", time.ctime())
        r_lock.acquire()# 锁中锁
        print(self.name, "got A", time.ctime())
        r_lock.release()
        r_lock.release()
    def run(self):
        self.actionA()
        self.actionB()
if __name__ == "__main__":
    L = []
    r_lock=threading.RLock()
    for i in range(5):
        t = Mythread()
        t.start()
        L.append(t)
    for t in L:
        t.join()
    print("ending>>>>>>>>>>")

  

需求:多个线程删除列表中的最后一个元素并删除

 L=[1,3,45,65,76,32,3254]
 def pri():
     while 1:
         a = L[-1]
         print(a)
         time.sleep(2)
         L.remove(a) # 按值来删除
         # L.pop(-1) # 按照索引删除
t1=threading.Thread(target=pri,args=())
t1.start()
t2=threading.Thread(target=pri,args=())
t2.start()

看运行结果、

 

(6)队列queue、是一种数据结构线程使用队列、数据是安全的

import queue
Li=[]
q=queue.Queue() # FIFO
# # q =queue.LifoQueue()# LIFO
# q =queue.PriorityQueue(4) # 优先级s
q.put([4,234])
q.put_nowait([2,"hello"])
q.put([3,{"name","alex"}])
q.put([5,{"gendle":"女"}],)
# q.put(78,block=False) # 队列已满时报错
# q.put_nowait(78) # 队列已满时报错
while 1:
    # data=q.get()
    data = q.get(block=False)
    # data =q.get_nowait()  # 为空时报错
    print(data)
    # print(q.qsize())
    # print(q.empty())
    # print(q.full())
    # print(data[1])
    time.sleep(1)
    print("----------")

(7)同步对象Event、保证所有的线程中状态完全一致‘

import threading
import time
‘‘‘同步对象Event 保证所有的线程中状态完全一致‘‘‘
class teacher(threading.Thread):
    def run(self):
        print("teacher: 明天把之前的作业留的作业都完成交上来")
        print("状态是否被设定",event.isSet())
        event.set()
        time.sleep(5)
        print("teacher:既然这样那下周一交上来")
        event.set()
class student(threading.Thread):
    def run(self):
        event.wait() # 一旦event.set() 则event.wait()==pass
        print("student:啊那么多怎么可能一天完成啊!!!!!")
        time.sleep(2)
        event.clear()
        event.wait()
        print("student:ohyear!!")
if __name__ == "__main__":
    event = threading.Event()
    threads=[]
    for i in range(6):
        threads.append(student())
    threads.append(teacher())
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    print("所有的都结束了")

  

以上是关于python 多线程的主要内容,如果未能解决你的问题,请参考以下文章

[Python3] 043 多线程 简介

python中的多线程和多进程编程

多线程 Thread 线程同步 synchronized

多个用户访问同一段代码

在 Python 多处理进程中运行较慢的 OpenCV 代码片段

线程学习知识点总结