进程线程协程

进程

资源分配调度的基本单位,有独立功能,每个进程都有独立内存空间。不同进程通过队列来进行通讯。可以使用多核CPU资源的。
同步执行:一个进程执行完后,另一个进程执行,有顺序
异步执行:多个进程同时进行(打群架,不solo)
状态:就绪,阻塞,运行,死亡

基本操作

import multiprocessing
import os
import time


def jump(*number_tuple):
	# (1, 2, 3)
	print(number_tuple)
	for i in range(10):
		# 我喜欢马小跳 <Process name='我的进程' parent=2950 started> 当前进程为 2952
		print('我喜欢马小跳', multiprocessing.current_process(), '当前进程为', os.getpid())
		print'当前的父进程为', os.getppid())
		time.sleep(2)


if __name__ == '__main__':
	# 实例化进程对象
	process1 = multiprocessing.Process(target=jump, args=(1, 2, 3), name='我的进程')
	# 调用start方法来启动
	process1.start()
	print('---------分割线-----------')
	print('我是主进程', multiprocessing.current_process(), '当前进程为', os.getpid() '当前父进程为', os.getppid())
	# 1.进程守护 主进程结束 子进程自行了断生命
	process1.daemon = True
	# 2.主动干掉子进程
	# process1.terminate()
	# 主进程自行了断
	exit()

进程池

import multiprocessing
import time


def copy():
	print('拷贝文件', multiprocessing.current_process())
	time.sleep(0.5)


if __name__ == '__main__':
	# 创建有3个进程的进程池
	process_pool = multiprocessing.Pool(3)
	for i in range(10):
		# 异步方式,3个进程同时执行 传参方式 pool.apply(函数, 参数元组)
		pool.apply_async(copy)
	# 表示不再接收新的任务 但是进程池还可以操作旧的任务
	pool.close()
	pool.join()	# join应在close后面

进程间通信—消息队列(mac使用有坑)

import multiprocessing
import time


def read(queue1):
	for i in range(10):
		if queue1.full() is True:
			print('队列满了')
			return
		queue1.put(i)
		time.sleep(0.5)
		print('%s 进入队列' % i)


def write(queue2):
	while True:
		# queue2.qsize
		if queue2.empty():
			print('队列空的,等待消息进入队列')
			return
		value = queue2.get()
		time.sleep(0.5)
		print('%s 出队列', value)


if __name__ == '__main__':
	# 定义队列的容量为5
	gl_queue = multiprocessing.Queue(5)
	process1 = multiprocessing.Process(target=read, args=(gl_queue, ))
	process2 = multiprocessing.Process(target=write, args=(gl_queue, ))
	process1.start()
	process1.join()
	process2.start()

进程池间的消息队列

import multiprocessing
import time


def read(queue1):
	for i in range(10):
		if queue1.full() is True:
			print('读取完成')
		queue1.put(i)
		time.sleep(0.5)
		print('%s 进入队列' % i)


def write(queue2):
	while True:
		if queue2.empty():
			print('写入完成,队列为空,等待数据写入')
			return
		value = queue2.get()
		time.sleep(0.5)
		print('%s 移出队列' % value)


if __name__ == '__main__':
	# 实例话 进程池 和 消息队列
	pool = multiprocessing.Pool(2)
	queue = multiprocessing.Manager().Queue(5)
	# 同步执行
	# pool.apply(read, args=(queue, ))
	# pool.apply(write, args=(queue, ))
	# 异步执行
	result = pool.apply_async(read, args=(queue, ))
	# 如join(),让其他进程等待,直到write任务完成
	result.wait()
	pool.apply_async(write, args=(queue, ))
	pool.close()
	pool.join()

线程

CPU调度的基本单位
同步:多任务之间执行有先后顺序,只有一个主线
异步:打群架
线程锁:(GIL,Global Interpreter Lock)CPU密集操作会产生互斥锁来限制线程对资源的访问,每个线程在执行的过程中都需要先获取GIL,保证同一时刻只有一个线程可以执行代码。多线程比单线程性能有提升,因为遇到IO阻塞会自动释放GIL锁,但执行完毕后,必须重新获取GIL锁。

同时虽然解释器存在GIL不意味着不用加Lock互斥锁了,GIL的释放时机是无法把控的,操作可能没有完成就释放。不想互斥锁那样用完才释放

互斥锁:多个线程几乎同时修改一个共享数据的时候,需要同步控制,将资源锁定,待该线程处理完成后,释放资源。
原则:尽可能少的锁定资源

死锁:两个及以上线程相互持有对方需要资源且都不释放

基本使用

import time
import threading
# 多线程间共享全局变量 多个线程共同操作全局变量 会产生资源局竞争问题 此时需要让线程插队
g_value = 10

def work1(para1, para2):
	for i in range(5):
		# 使用全局变量前需要声明
		global g_value
		print('正在执行工作1~~~~~', threading.currentThread(), 'g_value-', g_value)
		g_value += 1
		time.sleep(0.5)


def work2(para1, para2, para3):
	for i in range(5):
		global g_value
		print('正在执行工作2~~~~', threading.currentThread(), 'g_value-', g_value)
		time.sleep(0.5)


if __name__ == '__main__':
	# 创建线程实例 并传递参数 
	work1_threading = threading.Thread(target=work1, args=(1, 2))
	work2_threading = threading.Thread(target=work2, args=(1, ), kwargs={'b': 22, 'c': 32})

	# 方案2 创建守护线程 主线程结束 子线程自尽
	work1_threading.setDaemon(True)
	
	# 使用start线程才会执行
	work1_threading.start()
	# 让线程1进行插队
	work1_threading.join()
	work2_threading.start()
	
	# 主线程结束
	exit()

	# 方案1
	while True:
		# threading.enumerate()可以获取正在活跃的线程列表
		thread_list = threading.enumerate()
		# 只剩下主线程的时候 等待所有子线程执行完毕 只剩下主线程的时候结束循环
		if len(thread_list) <= 1:
			break
		time.sleep(0.5)

互斥锁

import threading
import time

g_value = 0


def work1():
	# 获取互斥锁
	lock1.acquire()
	for i in range(10000):
		global g_value
		g_value += 1
	lock1.release()
	print('work1~~~', g_value)


def work2():
	lock1.acquire()
	for i in range(10000):
		global g_value
		g_value += 1
	lock1.release()
	print('work2~~~', g_value)


if __name__ == '__main__':
	# 定义 全局互斥锁
	lock1 = threading.Lock()
	thread1 = threading.Thread(target=work1)
	thread2 = threading.Thread(target=work2)
	thread1.start()
	# thread1.join()
	thread2.start()
	if len(threading.enumerate()) == 1:
		time.sleep(2)
		print('sleep ing')
	print('main-', g_value)  

线程池

from concurrent.futures import ThreadPoolExecutor
def say_hello(iter_obj):
	for i in range(3)
		print('hello', threading.current_thread().getNmae(), '---', i)
		iter_obj += i
	return iter_obj
	
# 方案1
if __name__ == '__main__':
	with ThreadPoolExecutor(max_workers=5) as executor:
		# 数据并行化 函数 可迭代对象@[TOC](这里写自定义目录标题)
		results = executor.map(say_hello, range(100))
		for i in results:
			print (i)
	

# 方案2
if __name__ == '__main__':
	with ThreadPoolExecutor(max_workers=5) as executor:
		thread_pool = threadpool.ThreadPool(5)
		result1 = executor.submit(say_hello)
		result2 = executor.submit(say_hello)
		print(result1.result())
	
	

协程

(不适用于大量IO操作)
一个线程执行多人任务(协程),协程只使用一个线程(在不开皮新的线程的基础上实现多任务)。返回的数据是有序的,可以不加锁访问全局变量,所以上下文切换速度非常快。

greenlet实现协程

import time 
from greenlet import greenlet 


def work1():
	while True:
		print('我在执行work1~~~~~~~~1')
		coroutine2.switch()
		# 在此处添加switch切花
		time.sleep(0.5)

def work2():
	while True:
		print('我在执行work2~~~~~~~~~~~~~2')
		# 在此处添加switch切换
		corountine1.switch()
		time.sleep(0.5)

if __name__ == '__main__':
	corountine1 = greenlet(work1)
	corountine2 = greenlet(work2)
	# 创建出来的对象切换到任务1执行 
	corountine1.switch

gevent实现协程

import time
import gevent
from gevent import monkey


def work1():
	while True:
		print('我在执行work1~~~~~~')
		time.sleep(0.5)
		# gevent.sleep(0.5)
		
	def work2():
		while True:
			print('我在执行work2')
			time.sleep(0.5)
			# gevent.sleep(0.5)

if __name__ == '__main__':
	# 猴子补丁 来识别让协程识别time.sleep 识别耗时操作
	monkey.pathch.all()
	corountine1 = gevent.spawn(work1)
	corountine2 = gevent.spawn(work2)
	# 插队到主线程前执行
	corountine1.join()
	corountine2.join()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值