多线程多进程操作

多线程任务处理

多进程任务处理

协程多任务处理

线程(Thread)

    程序实际执行者是线程,线程称为轻量级进程,是一个cpu的执行单元,每个进程至少会有一个主线程

多线程编程

Python2中标准模块thread 和threading

Python3中模块_thread和 threading

_thread在最底层操作不易 一般推荐使用threading

 

_thread模块多线程并发

引入模块

Import _thread

获取当前线程编号

_thread.get_ident()

创建线程并执行函数

_thread.start_new_thread()

 

Threading模块属性和方法

 Thread类型属性和方法

Threading 模块的Thread

全局变量 global

定义函数外的变量赋值

 

 

Time.sleep()

让主程序暂停一定的时间,这样可以让子线程在主程序结束前运行结束

 

Threading.current_thread()

Threading.current_thread().getName()

Threading.get_ident()

获取当前运行线程对象  线程名称  线程端口

 

Threading.main_thread()

获取主线程对象

 

T1 = Threading.Thread(name, target, args)

创建线程

Target调用函数def

Args=(“tom”, ) 列表

 

T1.daemon = True

守护线程 ,当主线程结束,守护线程无论任务执行完成都将随着主线程的结束而结束

 

T1.start()

启动线程

 

T1.join()

独占: 让当前线程独占CPU时间片,直到当前线程运行结束

 

Print(t1.is_alive(),t2.is_alive())

判断线程存活状态,true线程正在运行 false 线程结束运行

当多个线程同时售票时会出现多个线程同售一张票的情况,这时就需要上锁进行独自售票

lock = threading.Lock() 同步锁/互斥锁

Lock = threading.Rlock() 可重用锁

 

锁的操作

Acquire() 上锁

Release() 解锁

Lock.acquire()

Lock.release()

 

当多个线程同时售票时需要先上锁然后再运算最后解锁,但是当运行到最后没有数据可以运行时就会结束循环无法解锁,这时就需要再循环外再加一个解锁的代码这样就完成了解锁的操作 不会再出现死锁的情况

死锁 dead lock

死锁时可以尝试使用可重用锁 可重用锁定义一次就行了 但还是会出现死锁的情况

可重用锁在锁定的基础上提供了一个计数器的操作counter,可以通过计算上锁的次数然后通过release解锁时就会重新运算计数器,等待计数器清零时所有的锁就全部释放了

死锁的问题一般遇不到

 

结束循环

break

 

事件对象  threading.Event

Set()添加标记

Wait() 线程等待  如果当前事件对象被标记 继续运行

Clear() 清除标记

 

Threading.Condition()

条件对象

Acquire() 上锁

Release() 解锁

Wait() 等待

Wait_for() 等待

Notify() 唤醒

Notify_all() 唤醒所有

 

队列 queue

先进先出 后进后出

先进后出  后进先出

线程队列

queue.Queue(10) 队列中可以存储的个数

为什么运行的时候生产者和消费者 要分开

 

异常处理 当try中的数据异常时执行except中的数据 这样程序不会报错

Try:

 

Except:

单词  范围  range  例:for I in range(5)

回顾列表 list []

添加数据

List.append()

删除数据

List.pop()

移除一个元素 默认最后一个,并且返回该元素的值

多线程的两种实现

函数式的多线程实现

Def

类型式的编程实现

Class

自主创建多个线程对象

T1 = Threading.thread()

T2 = threading.thread()

创建多个线程对象

class MyClazz(threading.Thread):

 

def __init__(self, name, info):

super().__init__(name=name)

self.info = info

 

def run(self):

print(self.info, "run()方法是线程执行的核心方法,在线程启动的时候会自动执行;不要自己去调用!")

 

通过类型创建线程

M1 = MyClass()

M1.start() 启动线程,自动执行创建的对象内部的run方法

 

Pdf 格式文件 可以将文件保存成pdf格式这样在任何地方打开文件格式都不会改变,并且不能修改

 

进程(Process)

进程中的属性和方法

Import multiprocessing, os

Os

Getpid(): 获取进程号

Getppid(): 获取父进程编号

Process

Name 进程名称

Ident 进程编号

Daemon 是否守护进程,默认false

Start(): 启动进程

Run(): 进程执行方法

Terminate(): 进程结束

Is_alive(): 判断进程是否存活

Join(): 独占模式,要求当前进程函数返回才能继续执行其他进程

进程和线程的使用方式大致相同

 基于函数的多进程

 基于类型的多进程

Multiprocessing.Process()

创建函数式进程

 

多线程模式下我们的全局变量是多个线程共享,

通过两种方式观察多进程模式下的数据处理

全局变量的数据

进程本身是独立运行的,多进程被运行多次,每个进程中的全局变量的数据是独立的

参数数据

多进程并发处理函数传递参数的方式,并不能被多个进程共享

函数执行并发操作是,每个进程都会单独拷贝一份当前进程的变量数据进行独立使用,不会互相影响

 

多进程的简化操作:进程池

Pool进程池 : 包含并且管理多个进程的一个对象

Multiprocessing.Pool(2)

创建一个进程池,该进程可以产生两个进程

 

Pool.apply_async(function, args, callback = ) 异步非阻塞执行一个函数

Pool.apply(function, args)同步执行一个函数,当进程中的函数执行完成才能退出 顺序执行

Callback 回调函数

将 download函数中返回的值 return返回值 给save_data(data)再调用

 

停止提交任务

Pool.close()

停止提交任务时才能向主线程申请内存 否则当主进程运行完成 进程池无法申请内存任务还在提交 并没有开始运行

 

独占模式: 让主进程等待进程池任务执行完成

Pool.join()

进程池中的进程 默认是主进程的守护进程

 

进程中操作哦变量数据,是独立的 非共享

多个进程都可以读取到全局变量的值

 

如何让进程之间完成数据共享|通信

  1. 通过第三方的东西进行交互

a进程将数据存储到文件|数据库中

b进程从文件|数据库中读取数据

文件|数据库是独立于a和b进程之外的数据类型完成进程之间的通信

 

通过第三方,独立于进程之外的数据类型完成进程间的通信

事件对象  进程之间的状态标记通信

Event = Multiprocessing.Event()

Event.set()

Event.clear()

Event.wait()

 

Conditon 条件类型

Queue 数据操作类型

 数据共享类型

 

管道类型 用于进程之间的协作 

args(tom, ) 参数传递

只有一个元素加逗号 不加逗号成了一个运算符

猜你喜欢

转载自blog.csdn.net/jinianh/article/details/81874111