Python开发Day9(多线程多进程)

python线程:

  • 介绍:

    • Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。

  • 使用:

    • Threading方法

      • .start() : 激活线程
      • .getName(): 获取线程的名称
      • .setName() : 设置线程的名称
      • .name : 获取或设置线程的名称
      • .is_alive() : 判断线程是否为激活状态
      • .isAlive() :判断线程是否为激活状态
      • .setDaemon() 设置为后台线程或前台线程(默认:False);通过一个布尔值设置线程是否为守护线程,必须在执行start()方法之后才可以使用。如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止;如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
      • .isDaemon() : 判断是否为守护线程
      • .ident :获取线程的标识符。线程标识符是一个非零整数,只有在调用了start()方法之后该属性才有效,否则它只返回None。
      • .join() :逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
      • .run() :线程被cpu调度后自动执行线程对象的run方法
    • 直接使用未加锁:

      import threading
      
      lock = threading.RLock()#定义一个线程锁
      def worker(num):
          print("Thread %d" % num)
      
      for i in range(20):
          t = threading.Thread(target=worker,args=(i,),name="t.%d" % i)
          t.start()#激活线程
      
      执行结果:
      Thread 0
      Thread 1
      Thread 2
      Thread 6
      Thread 4
      Thread 3
      Thread 5
      Thread 8
      Thread 10
      Thread 9
      Thread 7
      Thread 13
      Thread 12
      Thread 11
      Thread 16
      Thread 14
      Thread 15
      Thread 19
      Thread 18
      Thread 17

    • 使用加锁:

      import threading
      lock = threading.RLock()#定义一个线程锁
      def worker(num):
          lock.acquire()#加锁
          print("Thread %d" % num)
          lock.release()#解锁
      
      for i in range(20):
          t = threading.Thread(target=worker,args=(i,),name="t.%d" % i)
          t.start()#激活线程
      
      执行结果:
      Thread 0
      Thread 1
      Thread 2
      Thread 3
      Thread 4
      Thread 5
      Thread 6
      Thread 7
      Thread 8
      Thread 9
      Thread 10
      Thread 11
      Thread 12
      Thread 13
      Thread 14
      Thread 15
      Thread 16
      Thread 17
      Thread 18
      Thread 19

    • 线程锁有两种一种为RLock一种为Lock
      • Lock解析:

        lock = threading.Lock()#定义一个线程锁
        lock.acquire()#加锁
        print(123)
        lock.acquire()#加锁           产生了死锁
        print(234)
        lock.release()#解锁
        print(345)
        lock.release()#解锁
                #死锁,自己加锁后再次申请锁自己等待自己释放锁。
        
        执行结果:
        123
        一直等待~~~~~~~~~~

      • RLock解析:

        lock = threading.RLock()#定义一个线程锁
        lock.acquire()#加锁
        print(123)
        lock.acquire()#加锁
        print(234)
        lock.release()#解锁
        print(345)
        lock.release()#解锁
                #他不会产生死锁,但是需要注意产生了多少锁需要释放多少锁
        
        执行结果:
        123
        234
        345

线程间的通讯使用Event

    • 介绍:

      • Event是线程间通信最间的机制之一:一个线程发送一个event信号,其他的线程则等待这个信号。用于主线程控制其他线程的执行。 Events 管理一个flag,这个flag可以使用set()设置成True或者使用clear()重置为False,wait()则用于阻塞,在flag为True之前。flag默认为False。

    • 使用:

      • Event.wait([timeout]) : 堵塞线程,直到Event对象内部标识位被设为True或超时(如果提供了参数timeout)。

      • Event.set() :将标识位设为Ture

      • Event.clear() : 将标识伴设为False。

      • Event.isSet() :判断标识位是否为Ture。

      • 代码举例:

        import threading
        
        def do(event):
            print(‘start‘)
            event.wait()
            print(‘execute‘)
        
        event_obj = threading.Event()
        for i in range(10):
            t = threading.Thread(target=do, args=(event_obj,))
            t.start()
        
        event_obj.clear()
        inp = input(‘input:‘)
        if inp == ‘true‘:
            event_obj.set()
        
        执行结果:
        start
        start
        start
        start
        start
        input:true
        execute
        execute
        execute
        execute
        execute

        当线程执行的时候,如果flag为False,则线程会阻塞,当flag为True的时候,线程不会阻塞。它提供了本地和远程的并发性。

queue模块:

  • 介绍:

    • Queue 就是对队列,它是线程安全的(举例来说,我们去肯德基吃饭。厨房是给我们做饭的地方,前台负责把厨房做好的饭卖给顾客,顾客则去前台领取做好的饭。这里的前台就相当于我们的队列。

      这个模型也叫生产者-消费者模型。)

  • 使用:
    • 方法:

      import queue
      
      q = queue.Queue(maxsize=0)  # 构造一个先进显出队列,maxsize指定队列长度,为0 时,表示队列长度无限制。
      
      q.join()    # 等到队列为kong的时候,在执行别的操作
      q.qsize()   # 返回队列的大小 (不可靠)
      q.empty()   # 当队列为空的时候,返回True 否则返回False (不可靠)
      q.full()    # 当队列满的时候,返回True,否则返回False (不可靠)
      q.put(item, block=True, timeout=None) #  将item放入Queue尾部,item必须存在,可以参数block默认为True,表示当队列满时,会等待队列给出可用位置,
                               为False时为非阻塞,此时如果队列已满,会引发queue.Full 异常。 可选参数timeout,表示 会阻塞设置的时间,过后,
                                如果队列无法给出放入item的位置,则引发 queue.Full 异常
      q.get(block=True, timeout=None) #   移除并返回队列头部的一个值,可选参数block默认为True,表示获取值的时候,如果队列为空,则阻塞,为False时,不阻塞,
                            若此时队列为空,则引发 queue.Empty异常。 可选参数timeout,表示会阻塞设置的时候,过后,如果队列为空,则引发Empty异常。
      q.put_nowait(item) #   等效于 put(item,block=False)
      q.get_nowait() #    等效于 get(item,block=False)
    • 使用:

      import threading,queue
      message = queue.Queue(10)
      
      def producer(i):
          print(‘>>>>>‘,i)
          message.put(i)
      
      def consumer(i):
          msg = message.get()
          print(‘date‘,msg)
      
      for i in range(12):
          t = threading.Thread(target=producer, args=(i,))
          t.start()
      
      for i in range(10):
          t = threading.Thread(target=consumer, args=(i,))
          t.start()
      
      执行结果:
      >>>>> 0
      >>>>> 1
      >>>>> 2
      >>>>> 3
      >>>>> 4
      >>>>> 5
      >>>>> 6
      >>>>> 7
      >>>>> 8
      >>>>> 9
      >>>>> 10
      >>>>> 11
      date 0
      date 1
      date 2
      date 3
      date 4
      date 5
      date 6
      date 7
      date 8
      date 9

时间: 2024-10-12 05:52:30

Python开发Day9(多线程多进程)的相关文章

Python开发基础----多线程

概念 进程:进程就是一个程序在一个数据集上的一次动态执行过程 程序:代码 数据集:程序执行过程中需要的资源 进程控制块:完成状态保存的单元 线程:线程是寄托在进程之上,为了提高系统的并发性 线程是进程的实体 进程是一个资源管理单元.线程是最小的执行单元 线程和进程的关系 (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程.(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源.(3)CPU分给线程,即真正在CPU上运行的是线程. 进程/线程切换原则:切换的操作者,操

python-学习-python并发编程之多进程与多线程

一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程.Python提供了multiprocessing.    multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似.  multiprocessing模块的功能众多:支持子进程.通信和共享数据.执行不同形式的同步,

Python开发基础--- Event对象、队列和多进程基础

Event对象 用于线程间通信,即程序中的其一个线程需要通过判断某个线程的状态来确定自己下一步的操作,就用到了event对象 event对象默认为假(Flase),即遇到event对象在等待就阻塞线程的执行. 示例1:主线程和子线程间通信,代码模拟连接服务器 1 import threading 2 import time 3 event=threading.Event() 4 5 def foo(): 6 print('wait server...') 7 event.wait() #括号里可

Python开发基础-Day31 Event对象、队列和多进程基础

Event对象 用于线程间通信,即程序中的其一个线程需要通过判断某个线程的状态来确定自己下一步的操作,就用到了event对象 event对象默认为假(Flase),即遇到event对象在等待就阻塞线程的执行. 示例1:主线程和子线程间通信,代码模拟连接服务器 1 import threading 2 import time 3 event=threading.Event() 4 5 def foo(): 6 print('wait server...') 7 event.wait() #括号里可

Python进阶 - 多线程多进程基础

线程是最小的运行单元,进程是最小的资源管理单元. 串行 就是传统意义上的,同步,顺序的意思 进程:计算机中一个程序在一个数据集上 一次动态执行的过程,主要包含三部分内容 01>程序:描述进程的功能以及处理流程 02>数据集:功能处理过程中需要的资源数据 03>进程控制:严格控制进程执行过程中的各种状态 通俗来说,一个进程就是计算机上正在运行的一个程序 一个软件程序要运行,需要将软件依赖的数据加载到内存中,通过CPU进行运算并按照程序定义的逻辑结构进行流程控制,直到数据处理完成后程序退出

Python有了asyncio和aiohttp在爬虫这类型IO任务中多线程/多进程还有存在的必要吗?

最近正在学习Python中的异步编程,看了一些博客后做了一些小测验:对比asyncio+aiohttp的爬虫和asyncio+aiohttp+concurrent.futures(线程池/进程池)在效率中的差异,注释:在爬虫中我几乎没有使用任何计算性任务,为了探测异步的性能,全部都只是做了网络IO请求,就是说aiohttp把网页get完就程序就done了. 结果发现前者的效率比后者还要高.我询问了另外一位博主,(提供代码的博主没回我信息),他说使用concurrent.futures的话因为我全

关于Python和Java的多进程多线程计算方法对比

原文请见 关于Python和Java的多进程多线程计算方法对比 搞大数据必须要正视的一个问题就是并行计算.就像执行一件任务一样,大伙一起同时干,才有效率,才会很快出成果.正所谓"众人拾柴火焰高"~ 对于并行计算,有很多高大上的概念,我也不全懂.这里就单单罗列一下我对于多进程和多线程计算的理解和总结. 在计算机中,处理一个任务,可以在一个进程中,也可以在一个线程中,确切的说,执行的话都得靠一个个线程来.在我们做某件事的时候,往往需要同时干多个任务才能达到我们所要的效果,比如说看电影,就要

Python系列之多线程、多进程

一.python多线程 线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程. Python的标准库提供了两个模块:_thread和threading,_thread是低级模块,threading是高级模块,对_thread进行了封装.绝大多数情况下,我们只需要使用threading这个高级模块. import threading import time def f1(num)

python分别使用多线程和多进程获取所有股票实时数据

python分别使用多线程和多进程获取所有股票实时数据 前一天简单介绍了python怎样获取历史数据和实时分笔数据,那么如果要获取所有上市公司的实时分笔数据,应该怎么做呢? 肯定有人想的是,用一个列表存储所有上市公司的股票代号,然后无限循环获取不就得了吗? 现在深市和沪市的股票一共有3400多只,如果你真这样做的话,获取一次所有股票的实时数据需要十几二十秒的时间,甚至更多,而且非常容易因为等待超时而使程序挂掉,如果你的模型对实时数据的质量要求非常高,这肯定是不行的,即使不考虑数据质量,获取数据的