资讯详情

python的多线程

python多线程

一、线程概念

线程是CPU分配资源的基本单位。当一个程序开始运行时,它成为一个过程,一个过程相当于一个或多个线程。当没有多线程编程时,一个过程相当于一个主线程;当有多线程编程时,一个过程包含多个线程(包括主线程)。使用线程可以实现程序的大开发。

可在同一程序中运行多个线程,每个线程完成不同的任务。

多线程实现后台服务程序可以同时处理多个任务,并不发生阻塞现象。

多线程程序设计的特点是提高程序执行效率和处理速度。python多个相对独立的线程可以并行运行。

二、创建多线程

python支持两种创建多线程的方式:

~通过 threading.Thread () 创建。

~通过继承 threading.Thread 类的继承。

1.通过 threading.Thread () 创建

语法形式:

thread.Thread(group=Nore,targt=None,args=(),kwargs={},*,daemon=None) 

参数解释:

~group:必须为None,于ThreadGroup一般不使用类相关。

~target:线程调用的对象是目标函数。

~name:给线程起这个名字。Tread-x,x是序号,从1开始,创建的第一个线程名称是Tread-1。

~args:字典将关键字参数传递给目标函数。

~daemon:用于设置线程是否随主线程退出。

示例:

import threading def test (x,y):  for i in range(x,y):    print(i) thread1 = threading.Thread(name='t1',target= test,args=(1,10)) thread2 = threading.Thread(name='t2',target= test,args=(11,20)) thread1.start()   #启动线程1 thread2.start()   #启动线程2 

输出:

1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 

解释:两个程序并发运行,所以结果不一定是每次顺序1~10,这是根据CPU决定两行风马分配的时间片段。每次结果都不一样。

2.通过继承 threading.Thread 类的继承

threading.Thread它是一个可以继承的类别。

示例:

import threading class mythread(threading.Thread):   def run(self):     for i in range(1,10):       print(i) thread1 = mythread(); thread2 = mythread(); thread1.start() thread2.start() 

输出:

1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 

解释:自定义一类继承threading.Thread,然后重写父类run方法,线程启动(执行)start()该方法将自动执行。

三、主线程

在python主线程是第一个启动线程。

~父线程:如果在启动线程A中启动一个线程B,A是B的父线程。

~子线程:B是a的子线程。

有一个创建线程damon用它来判断主线程的属性。daemon设置False线程不会随着主线程的退出而退出,主线程会等待子线程的执行。daemon设置True当主线程退出时,线程将退出,其他子线程将强制退出。

使用daemon注意:

~daemon属性必须在start( )以前的设置,否则会造成RuntimeError异常

~每个线程都由daemon属性,可以显示设置也可以不设置,不设置默认值None

~若不设置子线程daemon属性取当前线程daemon来设置它。子子线程继承子线程的daemon值、功能和设置None一样。

~不设置从主线程创建的所有线程daemon属性,则默认为daemon=False。

示例:

import time import threading def test():  time.sleep(10)  for i in range(10):   print(i) thread1 = threading.Thread(target=test,daemon=False) thread1.start() print(主线程完成了) 

输出:

主线程完成 0 1 2 3 4 5 6 7 8 9 

说明:主线程运行完成输出后,等待输出0~9。如果将daemon=False该为daemon=True,则不会运行for i in range(10)语句。

四、堵塞线程

在另一个线程中调用另一个线程join在调用线程终止之前,方法阻塞了调用器。

语法形式:

join(timeout-=None) 

timeout 参数指定调用器等待多久,未设置时等待调用线程结束。其中一个线程可以是join多次调用。

示例:

import time import threading def test():  time.sleep(5)  for i in range(10):   print(i) thread1=threading.Thread(target=test) thread1.start() thread1.join() print(主线程完成了) 

输出:

0 1 2 3 4 5 6 7 8 9 主线程完成 

解释:在thread1.start()后加thread1.join()添加join输出时,主线程将等待输出~9后执行自己的print输出。

判断线程是否活动

~run():表示线程活动的方法

~start():启动线程

~join()

~isAlive():返回线程是否活动

~getName():返回线程名称

~setName() : 设置线程名称

示例:

from threading import Thread, Event import time def countdown(n, started_evt):     print(正在运行)     started_evt.set()     while n > 0:         print时间, n)         n -= 1         time.sleep(2) started_evt = Event() print(开始倒计时) t = Thread(target=countdown, args=(10, started_evt)) t.start() started_evt.wait() print(倒计时操作) 

输出:

开始倒计时 正在运行 时间 10 倒计时运行 时间 9 时间 8 时间 7 时间 6 时间 5 时间 4 时间 3 时间 2 时间 1 

Alive,顾名思义,它表示线程是否可用。如果线程已经启动,目前没有异常,则返回true,否则为false

Thread.isAlive() :顾名思义,这意味着当前线程处于可用状态,即是否已启动并运行;

六、线程同步

1.同步概念

在异步模式下,一个线程正在修改共享数据,另一个线程正在读取共享数据。当修改后的共享数据线程未完成时,读取数据的线程肯定会得到错误的结果。如果采用多线程同步控制机制,当共享数据的线程完成时,读取线程读取数据。

python解决了这个问题,锁定线程,只允许一个线程操作,其他线程排队等待,然后在当前线程操作完成后一个接一个地操作。

2. python的锁

python的threading模块提供了RLock锁定解决方案。只有一个线程操作的句子才能在一定时间内放置RLock的acquire方法和release方法之间,即acquire相当于给RLack上锁,而release相当于解锁。

示例:

import threding
class mythread(threading.Thread):
 def run(self):
  global x                   #声明一个全局变量
  lock.acquire()             #上锁
  x +=10
  print('%s:%d'%(self.name,x))
  lock.release()             #解锁
x = 0                        #设置全局变量初始值
lock = threading.RLock()     #创建可重入锁
list1 = []                   
for i in range(5):   
 list1.append(mythread())    #创建五个线程,放到同一列表中
for i in list1:
 i.start()                   #开启列表线程

输出:

Thread-1:10
Thread-2:20
Thread-3:30
Thread-4:40
Thread-5:50

解释:

3. python中的条件锁

条件锁常用的方法:

~acquire([timeout]):调用关联锁的方法

~release():解锁

~wait():使线程进入 Condition 的等待池等待通知并释放解锁。使用前线程必须已获得锁定,否则将抛出异常。

~notify():从等待池挑选一个线程并通知,收到通知的线程将自动调用 acquire() 尝试获得,其他线程仍然在等待池中等待通知,直到该线程收到通知 调用该方法,否则将会抛出异常。

~notify ALL():跟notify() 一样,但这个方法对应的是所有的线程。

示例:

题目:有几个生产车间生产,几个消费者购买,当生产达到一定数量时,停止生产。

import threading
import time
condtion = threading.Condition()
sheep = ['1件产品','1件产品','1件产品','1件产品','1件产品']
class Producer(threading.Thread):
    def __init__(self, name):
        super().__init__(name=name)
        pass
    def run(self):
        global condtion, sheep
        while True:
            time.sleep(0.1)
            condtion.acquire()
            if len(sheep) < 10:
                print(self.name + "生产了1件产品")
                sheep.append('1件产品')
                condtion.notifyAll()
                pass
            else:
                print("仓库满了,停止生产!")
                condtion.wait()
                pass
            condtion.release()
        pass
    pass
class Customer(threading.Thread):
    def __init__(self, name):
        super().__init__(name=name)
        pass
    def run(self):
        global condtion, sheep
        while True:
            time.sleep(0.1)
            condtion.acquire()
            if len(sheep) > 0:
                meat = sheep.pop()
                print(self.name + "购买了" + meat + "还剩多少" + str(len(sheep)) + "件")
                condtion.notifyAll()
                pass
            else:
                print("买光了,等待")
                condtion.wait()
                pass
            condtion.release()
        pass
    pass
if __name__ == "__main__":
    p1 = Producer("1号生产车间")
    p2 = Producer("2号生产车间")
    p3 = Producer("3号生产车间")
    p4 = Producer("4号生产车间")
    p5 = Producer("5号生产车间")
    p6 = Producer("6号生产车间")
    p1.start()
    p2.start()
    p4.start()
    p5.start()
    p6.start()
    c1 = Customer('小王')
    c2 = Customer('小李')
    c3 = Customer('小贾')
    c4 = Customer('小沈')
    c5 = Customer('小刘')
    c1.start()
    c2.start()
    c3.start()
    c4.start()
    c5.start()

标签: zl10n光电开关传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台