Python多线程

作者: 马本不想再等了 | 来源:发表于2019-02-23 12:56 被阅读16次

    1. 理解

    多个任务同时进行。
    Sublime、Chrome、Pycharm、QQ这四个进程同时开启并运行,CPU高速切换实现多进程。
    在QQ这一个进程中可以同时使进行语音、视频、文字的传输,这就是多线程。
    再理解。
    运行一段代码,系统就开启了一个进程,在代码中需要同时进行多个部分的运行,就需要创建多线程。

    2. 创建线程

    2.1 面向过程

    t = treading.Thread(target=xxx, name=xxx, args=(xx, xx))
    target:线程启动之后要执行的函数
    name:线程的名字
    args:主线程项子线程传递的参数
    threading.current_thread().name:获取当前线程的名字
    t.start():启动线程
    t.join():让主线程等待子线程结束
    实例代码如下:

    import threading
    import time
    
    
    def sing(a):
        print('线程%s,接收参数%s' % (threading.current_thread().name, a))
        for i in range(1, 4):
            print('我在唱什么')
            time.sleep(1)
    
    def dance(b):
        print('线程%s,接收参数%s' % (threading.current_thread().name, b))
        for i in range(1, 4):
            print('我在跳什么')
            time.sleep(1)
    
    def main():
        a = "彩云之南"
        b = "民族舞"
        # 创建唱歌线程
        tsing = threading.Thread(target=sing, name="唱歌", args=(a,))
        # 创建跳舞线程
        tdance = threading.Thread(target=dance, name='跳舞', args=(b,))
        # 启动线程
        tsing.start()
        tdance.start()
        # 让主线程等待子线程结束之后在结束
        tsing.join()
        tdance.join()
        # 主线程在运行
        print('这是主线程')
    
    if __name__ == '__main__':
        main()
    
    >>>线程唱歌,接收参数彩云之南
    >>>我在唱什么
    >>>线程跳舞,接收参数民族舞
    >>>我在跳什么
    >>>我在跳什么
    >>>我在唱什么
    >>>我在跳什么
    >>>我在唱什么
    >>>这是主线程
    

    2.2 面向对象

    定义一个类,继承自threading.Thread,重写run方法,需要线程名字、传递参数,重写构造方法,在重写构造方法的时候,一定要先手动调用父类的构造方法。
    实例代码如下:

    import threading
    import time
    
    
    # 写一个类,继承自threading.Thread
    class SingThread(threading.Thread):
        def __init__(self, name, a):
            super().__init__()
            self.name = name
            self.a = a
    
        def run(self):
            print('线程%s,接收参数%s' % (self.name, self.a))
            for i in range(1, 3):
                print('我在唱七里香')
                time.sleep(1)
    
    class DanceThread(threading.Thread):
        def __init__(self, name, b):
            super().__init__()
            self.name = name
            self.b = b
    
        def run(self):
            print('线程%s,接收参数%s' % (self.name, self.b))
            for i in range(1, 3):
                print('我在跳广场舞')
                time.sleep(1)
    
    def main():
        # 创建线程(实例化)
        tsing = SingThread('sing', '周杰伦的歌')
        tdance = DanceThread('dance', '外面广场的')
        # 启动线程
        tsing.start()
        tdance.start()
        # 让主线程等待结束
        tsing.join()
        tdance.join()
        print('主线程和子线程全部结束')
    
    if __name__ == '__main__':
        main()
    >>>线程sing,接收参数周杰伦的歌
    >>>我在唱七里香
    >>>线程dance,接收参数外面广场的
    >>>我在跳广场舞
    >>>我在唱七里香
    >>>我在跳广场舞
    >>>主线程和子线程全部结束
    

    2.3 线程同步

    线程之间共享全局变量,很容易发生数据紊乱问题,这个时候要使用线程锁。

    # 创建锁
    suo = threading.Lock()
    # 获取锁
    sou.acquire()
    # 释放锁
    sou.release()
    

    2.4 队列(queue)

    以爬虫为例会有下载线程,解析线程等。
    q = Queue(5) 创建队列,且最大存储量为5
    q.put('xxx') 如果队列满,程序卡在这里等待
    q.put('xxx', False) 如果队列满,直接报错
    q.put('xxx', Ture,3) 如果队列满,等待3s,后报错
    获取数据
    q.get() 如果队列空,程序卡在这里等待
    q.get(False) 如果队列空,直接报错
    q.get(True, 3) 如果队列空,等待三秒,再报错
    常用方法
    q.empty() 判断队列是否为空
    q.full() 判断队列是否已满
    q.qsize() 获取队列长度
    实例代码如下:

    from queue import Queue
    
    
    # 创建队列
    q = Queue(5)
    # 存数据
    q.put('Python')
    q.put('Java')
    q.put('Golang')
    q.put('C#')
    q.put('C++')
    # 队列满,直接报错
    # q.put('C', False)
    # 队列满,等待三秒,再报错
    # q.put('C', True, 3)
    # 取数据
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())
    # 队列空,直接报错
    # print(q.get(False))
    # 队列空,等待三秒,再报错
    # print(q.get(True, 3))
    

    相关文章

      网友评论

        本文标题:Python多线程

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