美文网首页
Python -- 多线程

Python -- 多线程

作者: 墨凌风起 | 来源:发表于2020-07-11 16:47 被阅读0次

    --coding:utf-8--

    2 python实现线程的方式

    '''
    1.函数方式(涉及_thread模块)
    2.用类包装线程对象(涉及threading模块)
    '''

    2.1函数方式实现多线程

    '''
    1.调用_thread模块的start_new_thread()函数创建并启动新线程
    语法:_thread.start_new_thread(function,args[,kwargs])
    function:线程函数
    args:传递给线程函数的参数,必须是tuple类型
    kwargs:可选参数
    '''
    '''
    import _thread
    import time
    def workThread(threadName,delay):
    print('[启动]>>>{0}'.format(threadName))
    counter = 0 #计数器
    for i in range(delay):
    counter += 1
    time.sleep(1)
    pass
    print('[停止]>>>{0}'.format(threadName))
    pass

    if name == 'main':
    _thread.start_new_thread(workThread,('thread-1',3))
    _thread.start_new_thread(workThread,('thread-2',5))
    for i in range(4):
    print('mainThread正在执行')
    time.sleep(1)
    pass
    print('>>>主线程mainThread停止\a')
    print('-' * 50)

    '''
    '''
    备注:线程结束一般依靠线程函数的自然结束,也可在线程中调用thread.exit(),抛出SystemExit exception 达到退出线程的目的
    '''

    2.2模块实现方式

    '''
    python通过两个标准库_thread和threading提供线程支持
    _thread提供低级别的,原始的线程以及一个简单的锁
    threading模块提供其他方法:
    1.threading.currentThread():返回当前线程变量
    2.threading.enumerate():返回一个包含正在运行线程的list,正在运行线程启动后,结束前,不包括启动前和终止后的线程
    3.threading.activeCount():返回正在运行的线程数量,与len(threading.enumerate())有相同的结果

    除此之外,线程模块提供threading.Thread类来处理线程,threading.Thread提供如下函数
    1.run():表示线程活动的方法
    2.start():启动线程活动
    3.join([time]):等待至线程中止,这阻塞调用线程直至线程的join()方法被调用中止-正常退出或者抛出未处理的异常-或者是可选
    4.isAlive():返回线程是否是活动的
    5.getName():返回线程名
    6.setName():设置线程名

    语法:
    import threading

    创建线程类

    class 线程类名称(threading.Thread):

    def __init__(self,参数1,...,参数N):
        #调用父类构造方法
        threading.thread.__init__(self)
        ...
    #重写run(),线程启动后的调用
    def run():
        ...
    

    线程对象 = 线程类名称()
    线程对象.run() #启动线程
    '''
    '''
    import threading
    import time
    exitFlag = 0 #创建推出标志位变量

    def outputTime(threadName,delay,counter):
    while counter:
    if exitFlag:
    threading.Thread.exit()
    time.sleep(delay)
    print('%s:%s' % (threadName,time.ctime(time.time())))
    counter -= 1
    pass
    pass

    class MyThread(threading.Thread):
    """docstring for MyThread"""
    def init(self, threadID,name,counter):
    threading.Thread.init(self)
    self.threadID = threadID
    self.name = name
    self.counter = counter

    def run(self):
        print('启动>' + self.name)
        outputTime(self.name,self.counter,5)
        print('结束>' + self.name)
        pass
    

    if name == 'main':
    print('mainThread主线程启动.....')
    thread1 = MyThread(1,'thread-11',1)
    thread2 = MyThread(2,'thread-22',1)
    thread1.run()
    thread2.run()
    print('mainThread主线程结束')
    '''

    3.线程同步

    '''
    线程有五个状态,状态切换如下
    启动 调度 结束
    新建 就绪 运行 死亡
    | 阻塞条件
    阻塞

    所线程在执行时为随机模式,不可控,要求执行顺序可控就得用线程同步
    Python 线程同步技术的解决方案:锁同步和条件变量同步

    3.1创建线程锁的语法:
    线程锁对象 = Threading.Lock
    锁定:线程锁对象.acquire()
    解除锁定:线程锁对象.release()

    使用场景:
    def run(self):
    线程锁对象.acquire()
    ...线程执行语句...
    线程锁对象.release()

    3.2条件变量同步

    python 提供的Condition对象提供了对复杂线程同步问题的支持
    Condition被称为条件变量,除了提供Lock类似的acquire和release方法,还提供wait和notify
    工作原理:
    线程首先acquire一个条件变量,然后判断一些条件,不满足wait,满足进行处理改变条件后,通过notify方法通知其他线程,其他处于wait的线程接到通知会重新判断条件,重复这一过程,从而解决复杂的同步问题
    '''

    示例:生产者和消费者

    '''
    生产者消费者问题(有限缓冲问题),是一个多线程同步的经典案例,该问题描述两个共享固定大小缓存的线程--即所谓的‘生产者‘和’消费者‘在实际运行时会发生的问题
    生产者作用时生成一定量的数据放到缓冲区,重复此过程
    消费者在缓冲区消耗这些数据
    该问题的【关键】保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区空时消耗数据
    任务说明:
    1.创建一个共享区,容量是10
    2.两个生产者,随机时间单位产生1件商品放入共享区,count + 1,共享区满,生产者停止放入共享区,线程进入block阻塞状态,等待消费者线程唤醒
    3.五个消费者,随机时间单位产生从共享区取1件商品,count - 1,共享区空,消费者停止从共享区获取,线程进入block阻塞状态,等待生产者线程唤醒
    '''
    import threading
    import time
    import random #随机模块

    使用共享区模拟变量

    count= 0

    创建条件对象

    condition = threading.Condition()

    生产者线程类

    class Producer(threading.Thread):
    def init(self,threadName):
    threading.Thread.init(self)
    self.threadName = threadName

    def run(self):
        global count #引用全局共享变量count
        while True:
            #使用条件变量后去锁并速定
            if condition.acquire():
                #判断共享变量是否达到上限(已满)
                if count >= 10:
                    print('共享区已满,生产者Producer线程进入阻塞block状态,停止放入!')
                    #当前线程进入阻塞状态
                    condition.wait()
                else:
                    count += 1 #共享变量自增1
                    print(time.ctime() + ' ' + self.threadName + '生产了1件商品放入共享区,共享区商品总计个数:{0}'.format(count))
                    condition.notify() #唤醒其他阻塞线程
                condition.release()
                time.sleep(random.randrange(10)/5) #随机休眠N秒
    

    消费者线程

    class Customer(threading.Thread):
    def init(self, threadName):
    threading.Thread.init(self)
    self.threadName = threadName

    def run(self):
        global count #引用全局共享变量count
        while True:
            #使用条件变量后去锁并速定
            if condition.acquire():
                #判断共享变量是否达到上限(已满)
                if count < 1:
                    print('共享区已空,消费者Customer线程进入阻塞block状态,停止获取!')
                    #当前线程进入阻塞状态
                    condition.wait()
                else:
                    count -= 1 #共享变量自减1
                    print(time.ctime() + ' ' + self.threadName + '消费了1件商品,共享区商品总计个数:' + str(count))
                    condition.notify() #唤醒其他阻塞线程
                condition.release()
                time.sleep(random.randrange(10)) #随机休眠N秒
    

    if name == 'main':
    for i in range(2):
    p = Producer('[生产者-' + str(i + 1) + ']')
    p.start()

    for i in range(5):
        c = Producer('[消费者-' + str(i + 1) + ']')
        c.start()
    

    相关文章

      网友评论

          本文标题:Python -- 多线程

          本文链接:https://www.haomeiwen.com/subject/tguicktx.html