python thread模块,threading.thread python

  python thread模块,threading.thread python

  本文主要介绍Python常用模块的线程化、线程模块和线程通信。文章围绕主题详细介绍了相关内容,具有一定的参考价值。有需要的朋友可以参考一下方法。

  00-1010 1.线程通信1.1互斥锁1.2线程间共享全局变量1.3共享内存间的竞争1.4使用锁控制共享资源的访问分析在这个阶段,我们会发现进程和线程的痛点!2.队列基本概念概述。

  

目录

 

  

1. 线程通信

 

  在多线程中,所有变量由所有线程共享。所以线程间共享数据最大的危险就是多个线程同时修改一个变量,一塌糊涂,所以我们需要一个互斥体来锁定数据。

  

1.1 互斥锁

 

  注意:

  因为线程属于同一个进程,所以它们共享一个内存区域。因此,全局变量是公共的。

  # -*-编码: utf-8 -*-

  导入线程

  a=1

  定义函数():

  全球a

  a=2

  t=螺纹。线程(target=func)

  启动()

  t.join()

  打印(一份)

  

1.2 线程间全局变量的共享

 

  先来个正常的例子,不用多线程:

  # -*-编码: utf-8 -*-

  x=0

  n=1000000

  定义a(n):

  全球x

  对于范围(n):内的I

  x=1

  定义b(n):

  全球x

  对于范围(n):内的I

  x -=1

  一个名词

  b(名词)

  打印(x)

  输出肯定和大家想的一样,毫无疑问是0!

  # -*-编码: utf-8 -*-

  从线程导入线程

  x=0

  n=1000000

  定义a(n):

  全球x

  对于范围(n):内的I

  x=1

  定义b(n):

  全球x

  对于范围(n):内的I

  x -=1

  if __name__==__main__:

  a=线程(target=a,args=(n,))

  b=线程(target=b,args=(n,))

  a .开始()

  b .开始()

  #一定要加屏蔽,因为你可以结合第一条说的自己思考~

  a .加入()

  加入()

  打印(x)

  提示:

  如果1000000不行,可以继续在后面加0,你会发现这个结果很奇怪!

  

1.3 共享内存间存在竞争问题

 

  互斥量介绍如下。

  在多线程中,所有变量由所有线程共享。所以线程间共享数据的最大危险在于多个线程同时修改一个变量 , 那就乱套了,所以我们只要操作全局变量就需要互斥锁 , 来锁住数据.可以在操作前锁定,操作后解锁,这样就解决了资源竞争的问题!第一种实现:

  # -*-

  coding: utf-8 -*-

  from threading import Thread, Lock

  a = 0

  n = 100000 # 指定加减次数

  # 线程锁

  lock = Lock()

  def incr(n):

   global a

   # 对全局变量a做n次加1

   for i in range(n):

   lock.acquire()

   a += 1

   lock.release()

  def decr(n):

   global a

   # 对全局变量a做n次减一

   for i in range(n):

   lock.acquire()

   a -= 1

   lock.release()

  t_incr = Thread(target=incr, args=(n, ))

  t_decr = Thread(target=decr, args=(n, ))

  t_incr.start(); t_decr.start()

  t_incr.join(); t_decr.join()

  print(a)

  

 

  第二种实现:

  

# -*- coding: utf-8 -*-

 

  

 

  

 

  

分析此阶段,我们会发现进程和线程的痛点!!!

 

  线程之间如何进行协作?

  最典型的例子就是生产者/消费者模式:若干个生产者线程向队列中写入数据,若干个消费者线程从队列中消费数据。
(功能!)

  

  • 1.定义了一个生产者类,一个消费者类。

  • 2.生产者类循环100次,向同步队列当中插入数据。

  • 3.消费者循环监听同步队列,当队列有数据时拉取数据。

  • 4.如果队列满了(达到5个元素),生产者阻塞。

  • 5.如果队列空了,消费者阻塞。

 

   这里就引入了协程!是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。
最重要的是,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源。

  代码走起来(依旧是生产者/消费者模式的例子!):

  

def consumer():

 

  代码中创建了一个叫做consumer_result的协程,并且在主线程中生产数据,协程中消费数据。
其中 yield 是python当中的语法。当协程执行到yield关键字时,会暂停在那一行,等到主线程调用send方法发送了数据,协程才会接到数据继续执行。
但是,yield让协程暂停,和线程的阻塞是有本质区别的。协程的暂停完全由程序控制,线程的阻塞状态是由操作系统内核来进行切换。

  因此,协程的开销远远小于线程的开销!!!

  执行结果:

  

 

  

 

  

2. 队列的基本概念

 

  

  • 一个入口,一个出口;

  • 先入先出(FIFO)。

 

  

 

  

import queue

 

  队列操作一览:

  

  • 入队: put(item)

  • 出队: get()

  • 测试空: empty()

  • 测试满: full()

  • 队列长度: qsize()

  • 任务结束: task_done()

  • 等待完成: join()

 

  注意:

  

  • get()等待任务完成,如果不加task_done()则不表示任务完成,只要加这句才表明完成。才会结束执行。

  • join就是阻塞,直到这个任务完成(完成的标准就是每次取出都task_done()了)

 

  简单使用队列的方法:

  

# -*- coding: utf-8 -*-

 

  

 

  

 

  

总结

 

  到此这篇关于Python常用模块之threading和Thread模块及线程通信的文章就介绍到这了,更多相关Python线程通信内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: