当前位置: 首页 > news >正文

Python多线程(二): 线程同步 生产者消费者模式 ThreadLocal线程局部变量

线程同步 

     同步就是协同步调,按预定的先后次序进行运行。例如:开会。“同”字指协同、协助、互相配合。

     如进程、线程同步,可以理解为进程或线程 A 和 B 一块配合, A 执行到一定程度时要依靠 B 的某个结果,于是停下来,示意 B 运行, B 运行后将结果给 A, A 继续运行

 

线程同步应用
 

import time
from threading import Thread,Lock
import threading

lock1=Lock()
lock2=Lock()
lock3=Lock()
lock2.acquire()
lock3.acquire()

class Task1(Thread):
	def run(self):
		while True:
			if lock1.acquire():
				print('...task1...')
				time.sleep(1)
				lock2.release()

class Task2(Thread):
	def run(self):
		while True:
			if lock2.acquire():
				print('...task2...')
				time.sleep(1)
				lock3.release()

class Task3(Thread):
	def run(self):
		while True:
			if lock3.acquire():
				print('...task3...')
				time.sleep(1)
				lock1.release()

if __name__ == '__main__':
	t1=Task1()
	t2=Task2()
	t3=Task3()
	t1.start()
	t2.start()
	t3.start()

 

生产者-消费者模式

        生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入生产者和消费者模式

       生产者消费者模式通过一个容器来解决生产者和消费者的强耦合问题生产者和消费者之间不直接通信。 生产者生产商品, 然后将其放到类似队列的数据结构中, 消费者不找生产者要数据,而是直接从队列中取。 这里使用 queue 模块来提供线程间通信的机制,也就是说,生产者和消费者共享一个队列。生产者生产商品后,会将商品添加到队列中。消费者消费商品,会从队列中取出商品
 

import time
import threading
from queue import Queue

class Producer(threading.Thread):
	def run(self):
		global queue
		count=0
		while True:
			if queue.qsize()<1000:
				for i in range(100):
					count += 1
					msg = '生成产品' + str(count)
					queue.put(msg)
					print(msg)
			time.sleep(0.5)

class Consumer(threading.Thread):
	def run(self):
		global queue
		while True:
			if queue.qsize()>100:
				for i in range(3):
					msg=self.name+'消费了'+queue.get()
					print(msg)
			time.sleep(1)

if __name__ == '__main__':
	queue = Queue()
	p=Producer()
	p.start()
	time.sleep(1)
	c=Consumer()
	c.start()

 

ThreadLocal线程局部变量

       我们知道多线程环境下,每一个线程均可以使用所属进程的全局变量。如果一个线程对全局变量进行了修改,将会影响到其他所有的线程对全局变量的计算操作,从而出现数据混乱,即为脏数据。为了避免多个线程同时对变量进行修改,引入了线程同步机制,通过互斥锁来控制对全局变量的访问。所以有时候线程使用局部变量比全局变量好,因为局部变量只有线程自身可以访问,同一个进程下的其他线程不可访问


       从上面的实例可以看到每个函数一层一层调用都需要传递 std 参数,非常麻烦,如果使用全局变量也不行,因为每个线程处理不同的 Student 对象,不能共享。 因此 Python 还提供了ThreadLocal 变量,它本身是一个全局变量,但是每个线程却可以利用它来保存属于自己的私有数据,这些私有数据对其他线程也是不可见的
 

import threading

# 创建全局 ThreadLocal 对象:
local = threading.local()

def process_student():
	# 获取当前线程关联的 name:
	student_name = local.name
	print('线程名: %s 学生姓名:%s' % (threading.current_thread().name,student_name))

def process_thread(name):
	# 绑定 ThreadLocal 的 name:
	local.name = name
	process_student()

t1 = threading.Thread(target=process_thread, args=('张三',), name='Thread-A')
t2 = threading.Thread(target=process_thread, args=('李四',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()

 

相关文章:

  • 爬虫url去重策略
  • 爬虫中的深搜和广搜
  • Objective-C
  • MyOS(四):让内核突破512字节的限制
  • Go语言实现并发(协程)
  • 汇编语言相关知识
  • 面向对象的意义
  • 文本大数据挖掘项目(Go语言)
  • Python网络编程
  • CUDA与cuDNN
  • AI中的搜索(一)——启发式搜索 ((贪婪)最佳优先搜索 (Greedy)Best-First Search、A* 、迭代加深搜索 和 IDA* )
  • AI中的搜索(二)——对抗搜索(最小最大搜索Minimax、Alpha-Beta剪枝搜索、蒙特卡洛树搜索MCTS)
  • Web1.0 与 Web2.0 时代
  • HTTP服务器开发项目(Python)
  • IO多路复用(Select,Poll,Epoll)
  • ES6指北【2】—— 箭头函数
  • [NodeJS] 关于Buffer
  • 【笔记】你不知道的JS读书笔记——Promise
  • 【个人向】《HTTP图解》阅后小结
  • ComponentOne 2017 V2版本正式发布
  • Cookie 在前端中的实践
  • css系列之关于字体的事
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • javascript 总结(常用工具类的封装)
  • Magento 1.x 中文订单打印乱码
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 大数据与云计算学习:数据分析(二)
  • 代理模式
  • 聊聊flink的TableFactory
  • 前端_面试
  • 深入浅出webpack学习(1)--核心概念
  • 使用docker-compose进行多节点部署
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 小程序开发之路(一)
  • 如何正确理解,内页权重高于首页?
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #Lua:Lua调用C++生成的DLL库
  • #微信小程序:微信小程序常见的配置传旨
  • (java)关于Thread的挂起和恢复
  • (翻译)terry crowley: 写给程序员
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (十六)串口UART
  • (转)fock函数详解
  • **CI中自动类加载的用法总结
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .net程序集学习心得
  • .net打印*三角形
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET项目中存在多个web.config文件时的加载顺序
  • .Net中wcf服务生成及调用
  • @Import注解详解